Rysowanie sieci 3d - bryły platońskie


14

Jest to podstawowa wersja raczej trudniejszych Rysowanie sieci 3d - bryły Archimedesa .

Mam słabość do sieci 3d, które po wycięciu i złożeniu umożliwiają tworzenie kształtów 3d z papieru lub karty. Zadanie jest proste, napisz jak najkrótszy program, który rysuje sieci dla 5 brył platońskich. Wyjście powinno być plikiem obrazu w dowolnym rozsądnym wybranym formacie (png, jpg itp.).

Wszystkie pięć kształtów opisano na stronie http://en.wikipedia.org/wiki/Platonic_solid . Ich sieci wyglądają tak (pochodzą z http://www.newscientist.com/gallery/unfolding-the-earth/2 ).

wprowadź opis zdjęcia tutaj

Dane wejściowe: Liczba całkowita od 1 do 5. Załóżmy, że kształty są ponumerowane zgodnie z liczbą stron, które mają. Tak więc 1 byłby czworościanem, a 5 dwudziestościanem.

Dane wyjściowe: plik obrazu zawierający siatkę dla tego kształtu. Tylko kontur zawierający linie wewnętrzne jest OK. Nie trzeba wypełniać go kolorami

Możesz używać dowolnego języka programowania, który Ci się podoba, a także dowolnej biblioteki, która nie została stworzona specjalnie na potrzeby tego konkursu. Oba powinny być dostępne bezpłatnie jednak (w obu aspektach) online.

Przyjmę odpowiedź z najmniejszą liczbą znaków dokładnie za tydzień.

Zwycięzca. Tylko jeden uczestnik, ale było cudownie. Zwycięzcą jest ... Raufio za mój ulubiony kawałek golfa w historii.

Odpowiedzi:


8

Python, 456 429 381

import turtle as t
L="fl"
R="fr"
d=L*3+R*3
b=(d+R)*3
a=[b,120,L*3+"fflflffflflfrflflfffl"+R*4+"flf",90,b+"ffrfrflffrffrfrfrflflf",120,(R*5+L*5+R+L)*5+"rrfr"+L*5+R*2+L*2+R*4+"f",72,(d+"f")*5+"rfl"+((d+"b")*5)[:-1],120]
l=t.lt
f=t.fd
b=t.bk
r=t.rt
p=input()*2-2 
t.setup(.9,.9)
t.goto(-200,150)
t.clear()
for c in a[p]:exec c+"(a[p+1])"
t.getscreen().getcanvas().postscript(file="o")

Zaimplementowałem prymitywnego interpretera l r f bjako operatora, który porusza kursorem żółwia pod kątem kształtów. Za jednym razem obraca tylko jeden kąt. Skompresowałem łańcuchy, ponownie wykorzystując łańcuchy (coś w rodzaju podprogramów psuedo). Poza tym nie sprawdziłem, czy wybrałem najlepszą ścieżkę. Wyprowadza do pliku postscriptowego.

Małe wyjaśnienie kodu bez golfa:

import turtle as t
Left="fl"
Right="fr"
diamond= Left*3 + Right*3
tetrahedron=(d+R)*3 #used to be b

Importuje wbudowany moduł żółwia i definiuje makra, które skracają łańcuchy. Moduł żółwia używa poleceń do przemieszczania „żółwia” po ekranie (tj. Do przodu (100), w lewo (90))

netList=[
   #tetrahedron
   tetrahedron,120,
   #cube
   Left*3+"fflflffflflfrflflfffl"+Right*4+"flf",90,
   #octohedron, builds off the tetrahedron
   tetrahedron+"ffrfrflffrffrfrfrflflf",120,
   #dodecahedron
   (Right*5 + Left*5 + Right + Left)*5
    +"rrfr"+
    Left*5 + Right*2 + Left*2 + Right*4 + "f",72,
   #icosahedron
   (diamond+"f")*5 +"rfl"+((diamond+"b")*5)[:-1],120
]

Ta lista zawiera kąty i sekwencje ruchów. Czworościan został zapisany do ponownego użycia z oktoedrenami.

l=t.left
f=t.forward
b=t.back
r=t.right

Jest to część, która mi się podoba, tworzy lokalne funkcje jednoznakowe, dzięki czemu można skracać i automatyzować wywołania za pomocą wstępnie zdefiniowanych ciągów.

input=int(raw_input())*2-2 
t.setup(.9,.9)
t.goto(-200,150)
t.clear()

Zaczyna się to od pobrania danych wejściowych (od 1 do 5) i przekonwertowania ich na indeks wskazujący ciąg kształtu w netList. Te ustawienia żółwia, aby pokazać całą sieć. Można je pominąć, jeśli ich zadaniem jest tylko ich narysowanie, ale ponieważ potrzebujemy wyjścia obrazu, są one potrzebne.

for command in netList[input]:
    exec command+"(netList[input+1])"
t.getscreen().getcanvas().postscript(file="o")

Pętla for pobiera polecenia z ciągu sekwencji poleceń i wykonuje je, więc w przypadku ciągu typu „fl” wykonuje to „do przodu (kąt); w lewo (kąt);” wywołując nowo utworzone funkcje lokalne. ostatni wiersz wyświetla plik o nazwie „o”, który jest w formacie PostScript przy użyciu funkcji żółwia.

Aby uruchomić :

Skopiuj go do pliku i uruchom go stamtąd. Kiedy go uruchomisz, będzie czekał na liczbę od 1 do 5 (właśnie go zmieniłem, więc pyta przed ustawieniem żółwia). Po wprowadzeniu liczby pojawia się okno i rysuje siatkę. jeśli chcesz, żeby działało szybciej, możesz dodać t.speed(200)wcześniej setup.

Możesz skopiować i wkleić go do interpretera, ale gdy raw_input()zostanie wywołany, zużyje kolejny wprowadzony ciąg "t.setup(.9,.9)"zamiast liczby. Jeśli to zrobisz, skopiuj do raw_input(), wprowadź liczbę, a następnie skopiuj wklej resztę. Jest przeznaczony do działania jako całość. Lub możesz skopiować go do funkcji i wywołać.

Oto jego wyniki (przekonwertowane z PostScript):

Uwaga: ich położenie w oknie uległo zmianie, ale ich ogólny kształt jest taki sam.

czworościan sześcian oktaedr dwunastościan dwudziestościan

To trochę brutalna siła dla golfa kodowego, ale zmęczyło mnie próbowanie znalezienia spójnego wzoru między kształtami.


Bardzo blisko. Dwunastościan jest zdecydowanie trudniejszy.
felipa

@Raufio To bardzo miłe. Czy nie można zdefiniować trójkąta (lub kwadratu lub pięciokąta), a następnie po prostu go obrócić / przesunąć? Czy jest to skutecznie to, co zrobiłeś?
felipa

Rzeczywiście tak zrobiłem, ale z większymi kształtami. Na przykład dwudziestościan rysuje się, rysując dwa trójkąty, jeden na drugim, i przesuwając się do przodu 5 razy, a następnie resetując w nowym miejscu, ponownie rysując diament, a następnie powtarzając 5 razy. djest ciągiem, który robi dwa trójkąty, więc jest(d+'f')*5+setupPosition+(d+'b')*5
Raufio

@Raufio Kod do gry w golfa nie działa dla mnie. Otwiera okno, które jest w większości puste. Jeśli następnie naciśniesz return, otrzymam p = (ord (raw_input ()) - 49) * 2 TypeError: ord () oczekiwał znaku, ale znaleziono łańcuch o długości 0
felipa

1
@felipa setupsprawia, że ​​okno żółwia jest wystarczająco duże, aby utrzymać siatkę. To samo dotyczy goto, przesuwa „żółwia” do -200, 150. clearczyści utworzoną linię goto. Ich po prostu komendy do konfigurowania rysunku. p=(ord(raw_input())-49)*2przyjmuje liczbę od 1 do 5, odpowiadającą żądanemu kształtowi.
Raufio

6

Matematyka

Poza konkursem, nie jest to darmowy język (chyba że bezpłatny okres próbny liczy się jako bezpłatny)

f[n_] := PolyhedronData[ Sort[PolyhedronData["Platonic", {"FaceCount","StandardName"}]][[n,2]],
                                                                                       "NetImage"]

Stosowanie:

f /@ Range@5

Grafika matematyczna


1
Matematyka zdecydowanie nie jest darmowa w żadnym sensie. Bardzo ładna odpowiedź.
felipa

@felipa jest za darmo jak w piwie na Raspberry Pi.
shrx,

wiesz, na tym wolnym komputerze, raspberry pi
undergroundmonorail

6

Python 2 (z Cairo) - 239

from cairo import*
s=PSSurface(None,99,99)
g=Context(s)
g.move_to(30,20)
a=str([34,456,3455,568788,3454445555][input()-1])
f=6.28
for c in a+a[::-1]:exec'g.rel_line_to(8,0);g.rotate(f/int(a[0]));'*int(c);f=-f
g.stroke()
s.write_to_png('o')

Wyniki:

wyniki


3

Logo, 199 bajtów

TO p:d:n:s
rt :n*45 for[i 1 :n/8][pu setxy :d*:i 0 pd repeat 2[for[k 1 :s*2+2][fd 40 rt (360-720*(:k>:s))/:s] rt 720/:s]]END
TO q:j
apply "p item :j [[70 9 3][56 23 4][70 16 3][105 26 5][40 42 3]]END

Czytając to wstecz, widzę, że moja oryginalna wersja nie była zgodna ze specyfikacją, jak napisano (weź argument liczbowy i narysuj jeden kształt), ale raczej zgodnie z interpretacją niektórych innych odpowiedzi (narysuj wszystkie kształty). Nowa wersja to naprawia. Oczekuje, że zostanie wywołany jak na przykład q 5. csnależy to zrobić wcześniej, aby wyczyścić ekran i skierować żółwia na północ.

qwywołuje główną funkcję pz 3 argumentami. Składnia tego jest dość rozdęta, więc aby pobić mój poprzedni wynik, musiałem zgolić bajty gdzie indziej.

nowa wersja ppobiera 3 argumenty. Nie ma potrzeby, xa yponieważ wykreślamy tylko jedną sieć, ale dodstęp między podjednostkami pozostaje. s jest wciąż liczbą boków na wielokąt, a nteraz koduje dwie różne rzeczy>n/8 to liczba podjednostek do wykreślenia i n*45jest to kąt, o który żółw musi zostać obrócony przed rozpoczęciem (wykorzystując naturalny mod 360 do obrotu. )

Ulepszone zapętlenie umożliwia rysowanie slinii z obrotem w prawo is+2 linii z obrotem w lewo i w lewo w jednej pętli.

interpreter calormen wydaje się być teraz mniej tolerancyjny wobec braku białych znaków niż w momencie mojego pierwszego postu, ale kod działa dobrze na http://turtleacademy.com/playground/en

Logo, 200 bajtów

TO p:x:y:d:n:s
for[i 1:n][pu setxy:x:y-:d*:i if:i<>6[pd]repeat 2[repeat:s[fd 40 rt 360/:s]repeat:s+2[fd 40 lt 360/:s]rt 720/:s]]END
p 0 200 40 7 3
p 70 0 80 2 3
p -200 200 105 3 5
rt 45
p 90 90 56 2 4

Tłumacz na http://www.calormen.com/jslogo/# Zakłada się, że żółw wskazuje północ przed uruchomieniem programu. Użyj cspolecenia, aby wyczyścić ekran, skieruj żółwia na północ i umieść go na początku na środku ekranu.

wprowadź opis zdjęcia tutaj

Podstawową jednostką wszystkich powyższych sieci jest para wielokątów. Są one ułożone w 2 schodkowych rzędach, tworząc podjednostkę 4 wielokątów, które można przełożyć w pionie, aby utworzyć wszystkie sieci (z wyjątkiem ośmiościanu, który zaczepia o rysunek dwudziestościanu i czworościanu). Podjednostka tworzy 1 siatkę czworościanu, 1/5 siatki dwudziestościanu, 1/3 siatki dwunastościanu i 2/3 siatki sześcianu (narysowane są dwie podjednostki, a środkowe dwa kwadraty zachodzą na siebie.)

Nieskluczony kod

TO p :x :y :d :n :s                 ;x,y=starting point d=negative vertical offset for each iteration n=#of iterations s=# of sides on polygon
  for[i 1 :n][                      ;iterate n times 
    pu                              ;pen up
    setxy :x :y- :d* :i             ;move pen to start of iteration
    if :i<>6[pd]                    ;pen down (supressed for i=6 to enable part of octahedron to be drawn with icosahedron)
    repeat 2[                       ;draw lower row of 2 polygons, then upper row of 2 polygons
      repeat :s[fd 40 rt 360/ :s]   ;starting at lower left of polygon facing up, draw righthand polygon
      repeat :s+2[fd 40 lt 360/ :s] ;starting at lower right of polygon facing up, draw lefthand polygon, duplicating last two sides
      rt 720/ :s                    ;return turtle to upwards facing in order to draw second row
    ]
  ]
END
cs
p 0 200 40 7 3                      ;draw icosahedron and left side of octahedron (6th iteration is suppressed)
p 70 0 80 2 3                       ;draw right side of octahedron, and tetrahedron
p -200 200 105 3 5                  ;draw dodecahedron
rt 45                               ;turn turtle in preparation for drawing cube
p 90 90 56 2 4                      ;draw cube

@ phase haha, dzięki, naprawdę zastanawiałem się nad zrobieniem ht aby ukryć to dla obrazu. Cieszę się, że nie!
Level River St
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.