Styczne rozszerzenia wielokąta


11

Narysuj coś, co wygląda następująco:

wprowadź opis zdjęcia tutaj

Mówiąc dokładniej, narysuj okrąg o promieniu r, z n równomiernie rozmieszczonymi stycznymi liniami długości l. Połącz końce tych linii, aby utworzyć nowy n-stronny regularny wielokąt.

Zasady

r = promień okręgu
n = liczba linii stycznych - musi być równomiernie rozmieszczona wokół koła (n> = 3)
l = długość boku linii stycznych

Utwórz program, który akceptuje argumenty {r, n, l} i rysuje wymagane dane wyjściowe.

Jednostki są w pikselach.

Nie ma ograniczeń co do lokalizacji rysunku, o ile jest on widoczny.

Obraz jest dość oczywisty.

To jest golf golfowy, więc wygrywa najkrótszy kod w bajtach!


Zakładam, że n będzie> = 3, czy jest maksimum? Czy chcesz również stycznych i okręgu?
MickyT,

Tak, n> = 3, (przecięcie ok, jeśli l nie jest wystarczająco długie). Powinieneś narysować okrąg i styczne. Myślę, że maksimum jest w zasadzie, gdy wyjście jest zacienionym okręgiem. Innymi słowy, maksimum to realistyczne maksimum dla takiego rysunku.
Stretch Maniac

Czy jednostki pikseli mają zastosowanie nawet, jeśli tworzymy grafikę wektorową? Ponieważ w takim przypadku piksele są właściwie źle zdefiniowane. Czy też mają produkować rasterised grafiki?
Martin Ender

@ MartinBüttner, możesz zignorować jednostkę pikseli w (fantazyjnej) grafice wektorowej, jeśli istnieje jakaś skala (np. Oś).
Stretch Maniac

Odpowiedzi:


5

Mathematica, 135 132 131 123 123 bajtów

{r,n,l}=Input[];Graphics[{{0,0}~Circle~r,Line[Join@@Array[{b=(a=r{c=Cos[t=2Pi#/n],s=Sin@t})-l{s,-c},a,b}&,n+1]]},Axes->1>0]

Ten kod oczekuje danych wejściowych (za pomocą zachęty) dokładnie tak, jak określono w pytaniu: np {100, 6, 150}. Tworzy grafikę wektorową, więc dołączam oś, jak określono w komentarzach OP.

Zarówno styczne, jak i wielokąt są w rzeczywistości paskiem pojedynczej linii, przechodząc przez „narożnik wielokąta, punkt styczny, narożnik wielokąta, następny narożnik wielokąta, punkt styczności, narożnik wielokąta ...”

wprowadź opis zdjęcia tutaj

Gdyby nie oś, mógłbym to zrobić w 107 bajtach:

{r,n,l}=Input[];Graphics@{Circle[],Line[Join@@Array[{b=(a={c=Cos[t=2Pi#/n],s=Sin@t})-l/r{s,-c},a,b}&,n+1]]}

Dodatkowe oszczędności (oprócz Axes->1>0) wynikają z faktu, że mogę teraz przeskalować wszystko r, co upraszcza wezwanie do Circleuzyskania koła jednostek.


{0,0}~Circle~r
DavidC

@DavidCarraher heh, faktycznie zrobiłem to już w 135 bajtach, ale zapomniałem skopiować go z powrotem do mojego notebooka, więc został przywrócony, gdy dokonałem zmiany Unicode. dzięki!
Martin Ender

8

Python, 133 bajty

Jak dotąd jedyną odpowiedzią na zgodność z zasadą „Jednostki są w pikselach” ...

from turtle import*
c=circle
r,n,l=input()
lt(90)
exec'c(r,360/n);fd(l);bk(l);'*n
fd(l)
lt(towards(-r,0)-180)
c(distance(-r,0),360,n)

Dodaj exitonclick()na końcu, jeśli nie chcesz, aby okno natychmiast się zamykało.

Wynik:

python tangentpoly.py <<< "20, 6, 30":

wprowadź opis zdjęcia tutaj

python tangentpoly.py <<< "100, 8, 200":

wprowadź opis zdjęcia tutaj


1
for i in n*[0]:c(r,360/n);fd(l);bk(l)->exec'c(r,360/n);fd(l);bk(l)'*n;
isaacg


7

T-SQL 440 483

Nie zamierzam wygrać żadnych nagród, ale lubię rysować :)

Edytuj przekleństwa! Właśnie zauważyłem, że popsułem wielokąty narysowane w poprzek koła. Naprawiono kosztem.

SELECT Geometry::UnionAggregate(Geometry::Point(0,0,0).STBuffer(@r).STExteriorRing().STUnion(Geometry::STGeomFromText(CONCAT('LINESTRING(',@r*SIN(a),' ',@r*COS(a),',',@r*SIN(a)+@l*SIN(b),' ',@r*COS(a)+@l*COS(b),')'),0))).STUnion(Geometry::ConvexHullAggregate(Geometry::Point(@r*SIN(a)+@l*SIN(b),@r*COS(a)+@l*COS(b),0)).STExteriorRing())p FROM(SELECT RADIANS(360./@*N)a,RADIANS((360./@*N)-90)b FROM(SELECT TOP(@)row_number()OVER(ORDER BY(SELECT\))-1N FROM sys.types a,sys.types b)t)r

Wykonany z następującymi zmiennymi

declare @r float = 1.0
declare @ int = 10
declare @l float = 3.0

Uruchom w Sql Server Management Studio 2012+ zwróci to w zakładce wyników przestrzennych. wprowadź opis zdjęcia tutaj

Z

declare @r float = 1.0
declare @ int = 360
declare @l float = 3.0

wprowadź opis zdjęcia tutaj

z

declare @r float = 10.0
declare @ int = 3
declare @l float = 10.0

wprowadź opis zdjęcia tutaj

Rozbudowany

SELECT Geometry::UnionAggregate(    --group together lines
    Geometry::Point(0,0,0)          --Set origin
    .STBuffer(@r)                   --Buffer to @r
    .STExteriorRing()               --Make it a line
    .STUnion(                       --Join to the floowing tangent
        Geometry::STGeomFromText(   --Create a tangent line
            CONCAT('LINESTRING(',@r*SIN(a),' ',@r*COS(a),',',@r*SIN(a)+@l*SIN(b),' ',@r*COS(a)+@l*COS(b),')'),0)
        )
    ).STUnion( --Generate polygon around exterior points
    Geometry::ConvexHullAggregate(Geometry::Point(@r*SIN(a)+@l*SIN(b),@r*COS(a)+@l*COS(b),0)).STExteriorRing()
    )
    p
FROM(
    SELECT RADIANS(360./@*N)a,      --calclate bearings
        RADIANS((360./@*N)-90)b
    FROM(                           --make enough rows to draw tangents
        SELECT TOP(@)row_number()OVER(ORDER BY(SELECT\))-1N 
        FROM sys.types a,sys.types b
        )t
    )r 

5

MATLAB - 233 bajty

function C(n,r,l),t=2*pi/n;c=cos(t);s=sin(t);M=[c,s;-s,c];F=@(y)cell2mat(arrayfun(@(x){M^x*y},1:n));P=F([0;r]);Q=F([l;r]);v='k';t=1e3;t=2*pi/t*(0:t);R=[1:n 1];q=Q(1,R);s=Q(2,R);plot(r*cos(t),r*sin(t),v,[P(1,R);q],[P(2,R);s],v,q,s,v);

Przykładowa funkcja wyjściowa dla n = 8, r = 4, l = 6(dołączone osie wskazują długość jednostki): produkcja cykliczna

Przykładowe wyjście funkcji dla n = 1024, r = 4, l = 2: produkcja cykliczna


Wybieram nitki, ale Jednostki są w pikselach
Digital Trauma

3
@DigitalTrauma: Ah. Nie zauważyłem tego. Liczby MATLAB nie mają stałych jednostek; skalują się do okna. I w każdym razie jest to kwestia sporna. Twoje rozwiązanie oparte na LOGO w Pythonie ma moje mocne brzmienie. Przedtem nie wyobrażałem sobie, że ktoś może przenieść LOGO do Pythona, ale tak jest. Uczę się z biegiem czasu. : P
COTO

No i tak +1 :)
Cyfrowa trauma

Obraz jest prawie logo apertury.
dumny haskeller

4

HTML + JavaScript (E6) 298

Aby przetestować, zapisz jako plik HTML i otwórz za pomocą FireFox. Wstaw parametry r, n, l do pola wprowadzania, oddzielając przecinkami, a następnie tabuluj.

Lub spróbuj jsfiddle

<input onblur="
[r,n,l]=this.value.split(','),
z=r-~l,t=D.getContext('2d'),w='lineTo',
D.width=D.height=z*2,
t.arc(z,z,r,0,7);
for(C=1,S=i=0;i++<n;)
  t[w](x=z+r*C,y=z+r*S),
  t[w](x-l*S,y+l*C),
  C=Math.cos(a=6.283*i/n),
  S=Math.sin(a),
  t[w](z+r*C-l*S,z+r*S+l*C);
t.stroke()">
<canvas id=D>

Próbka wyjściowa

50,20,140

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.