Zeichnen von 3d-Netzen - platonische Körper

14

Dies ist eine Basisversion der etwas schwierigeren Drawing 3d-Netze - Archimedean Solid .

Ich habe eine Schwäche für 3D-Netze, die es Ihnen ermöglichen, 3D-Formen aus Papier oder Pappe herzustellen, wenn sie ausgeschnitten und gefaltet werden. Die Aufgabe ist einfach: Schreiben Sie das kürzeste Programm, mit dem Sie Netze für die 5 platonischen Körper zeichnen können. Die Ausgabe sollte eine Bilddatei in einem vernünftigen Format Ihrer Wahl (PNG, JPG usw.) sein.

Alle fünf Formen sind unter http://en.wikipedia.org/wiki/Platonic_solid beschrieben . Ihre Netze sehen so aus (entnommen aus http://www.newscientist.com/gallery/unfolding-the-earth/2 ).

Bildbeschreibung hier eingeben

Eingabe: Eine Ganzzahl von 1 bis 5. Angenommen, die Formen werden in der Reihenfolge der Anzahl der Seiten nummeriert. Also wäre 1 ein Tetraeder und 5 das Ikosaeder.

Ausgabe: Eine Bilddatei, die das Netz für diese Form enthält. Nur die Gliederung einschließlich der internen Leitungen ist in Ordnung. Es ist nicht notwendig, es mit Farben auszufüllen

Sie können jede beliebige Programmiersprache sowie jede Bibliothek verwenden, die nicht speziell für diesen Wettbewerb erstellt wurde. Beide sollten jedoch (in beiden Sinnen) online frei verfügbar sein.

Ich werde die Antwort mit der geringsten Anzahl von Zeichen in genau einer Woche annehmen.

Gewinner. Nur ein Teilnehmer, aber es war wunderbar. Der Gewinner ist ... Raufio für mein Lieblingsstück Code Golf aller Zeiten.

felipa
quelle

Antworten:

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")

Ich habe einen primitiven Interpreter mit l r f bOperatoren implementiert , die den Turtle-Cursor im Winkel der Formen bewegen. Auf einmal dreht es sich nur um einen Winkel. Ich habe die Zeichenfolgen komprimiert, indem ich Zeichenfolgen wiederverwendete (ähnlich wie bei Pseudo-Subroutinen). Ansonsten habe ich nicht überprüft, ob ich den besten Pfad verwendet habe. Es wird in eine Postscript-Datei ausgegeben.

Eine kleine Erklärung des Codes ohne Golfspiel:

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

Importiert das integrierte Turtle-Modul und definiert die Makros, die die Zeichenfolgen verkürzen. Das Schildkrötenmodul verwendet Befehle, um eine 'Schildkröte' über den Bildschirm zu bewegen (dh vorwärts (100), links (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
]

Diese Liste enthält die Winkel und Bewegungsabläufe. Das Tetraeder wurde für die Wiederverwendung mit den Oktoedern aufbewahrt.

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

Dies ist der Teil, den ich mag, es macht einzelne Zeichen lokale Funktionen, so dass die Aufrufe durch vordefinierte Zeichenfolgen verkürzt und automatisiert werden können.

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

Dies beginnt damit, dass die Eingabe (zwischen 1 und 5) in einen Index konvertiert wird, der auf die Formzeichenfolge in der Netzliste zeigt. Diese Setup-Schildkröte zeigt das ganze Netz. Diese könnten weggelassen werden, wenn die Aufgabe nur darin bestand, sie zu zeichnen, aber da wir eine Bildausgabe benötigen, werden sie benötigt.

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

Die for-Schleife nimmt die Befehle in der Befehlssequenzzeichenfolge und führt sie aus. Bei einer Zeichenfolge wie "fl" wird also "forward (angle); left (angle);" durch Aufrufen der neu erstellten lokalen Funktionen. Die letzte Zeile gibt eine Datei mit dem Namen 'o' im Postscript-Format mit der Turtle-Funktion aus.

Um zu rennen :

Kopieren Sie es in eine Datei und führen Sie es von dort aus. Wenn Sie es ausführen, wartet es auf eine Zahleneingabe zwischen 1 und 5 (ich habe es nur so geändert, dass es fragt, bevor Sie Turtle einrichten). Wenn Sie eine Zahl eingeben, wird ein Fenster geöffnet und das Netz gezeichnet. Wenn Sie möchten, dass es schneller geht, können Sie es t.speed(200)vorher hinzufügen setup.

Sie können es kopieren und in den Interpreter einfügen, aber wenn raw_input()es aufgerufen wird, wird der nächste eingegebene String "t.setup(.9,.9)"anstelle einer Zahl verwendet. Wenn Sie dies tun, kopieren Sie bis raw_input(), geben Sie eine Zahl ein, und kopieren Sie dann den Rest. Es soll als Ganzes ausgeführt werden. Oder Sie kopieren es in eine Funktion und rufen es auf.

Hier sind die Ausgaben (konvertiert von Postscript):

Hinweis: Die Position dieser Elemente im Fenster hat sich geändert, aber ihre Gesamtform ist dieselbe.

Tetraeder Würfel Oktaeder Dodekaeder Ikosaeder

Es ist ein bisschen brachial für Code-Golf, aber ich habe es satt, ein konsistentes Muster zwischen den Formen zu finden.

Raufio
quelle
Sehr nah. Das Dodekaeder ist definitiv schwieriger.
Felipa
@ Raufio Es ist sehr schön. Ist es nicht möglich, ein Dreieck (oder ein Quadrat oder ein Fünfeck) zu definieren und es dann einfach zu drehen / bewegen? Oder haben Sie das tatsächlich getan?
Felipa
Eigentlich ja, das habe ich getan, aber mit größeren Formen. Zum Beispiel wird das Ikosaeder gezeichnet, indem man zwei Dreiecke übereinander zeichnet, sich fünfmal vorwärts bewegt, dann an einer neuen Stelle zurücksetzt und den Diamanten erneut zurückzieht und dann fünfmal wiederholt. dist die Zeichenfolge, die die beiden Dreiecke tut, so ist es(d+'f')*5+setupPosition+(d+'b')*5
Raufio
@Raufio Der Golfcode funktioniert bei mir nicht. Es öffnet sich ein Fenster, das größtenteils leer ist. Wenn ich dann drücken Sie die Eingabetaste I get p = (ord (raw_input ()) - 49) * 2 Typeerror: ord () erwartet einen Charakter, aber String der Länge 0 gefunden
Felipa
1
@felipa setupmacht das Schildkrötenfenster groß genug, um das Netz zu halten. Gleiches gilt goto, es bewegt die 'Schildkröte' auf -200, 150. clearlöscht die Linie von goto. Ihre gerechten Befehle zum Einrichten des Zeichnens. p=(ord(raw_input())-49)*2nimmt eine Zahl zwischen 1 und 5 an, die der gewünschten Form entspricht.
Raufio
6

Mathematica

Außerhalb des Wettbewerbs, keine freie Sprache (es sei denn, eine kostenlose Testversion gilt als kostenlos)

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

Verwendung:

f /@ Range@5

Mathematica-Grafiken

Dr. belisarius
quelle
1
Mathematica ist definitiv in keiner Hinsicht frei. Sehr nette Antwort jedoch.
Felipa
@felipa es ist kostenlos wie in Bier auf dem Raspberry Pi.
shrx
Sie wissen, auf diesem kostenlosen Computer, die Himbeer-Pi
U-Bahn-
6

Python 2 (mit Kairo) - 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')

Ergebnisse:

Ergebnisse

aditsu
quelle
3

Logo, 199 Bytes

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

Als ich das zurücklese, sehe ich, dass meine ursprüngliche Version nicht der Spezifikation entsprach (nimm ein numerisches Argument und zeichne eine Form), sondern wie von einigen der anderen Antworten interpretiert (zeichne alle Formen). Die neue Version behebt dies. Es erwartet, wie zum Beispiel genannt zu werden q 5. cssollte vorher gemacht werden, um den Bildschirm zu löschen und die Schildkröte nach Norden zu richten.

qruft die Hauptfunktion pmit 3 Argumenten auf. Die Syntax dafür ist ziemlich aufgebläht. Um meine vorherige Punktzahl zu übertreffen, musste ich Bytes an anderer Stelle entfernen.

Die neue Version von pbenötigt 3 Argumente. Es ist nicht nötig xund yweil wir nur ein Netz zeichnen, aber dder Abstand zwischen den Untereinheiten bleibt bestehen. s ist immer noch die Anzahl der Seiten pro Polygon und nkodiert nun für zwei verschiedene Dinge> n/8ist die Anzahl der zu zeichnenden Untereinheiten und n*45ist ein Winkel, um den die Schildkröte vor dem Start gedreht werden muss (unter Ausnutzung des natürlichen Mods 360 für Rotationen. )

Verbessertes Looping ermöglicht das Zeichnen von sLinien mit Rechtsdrehung und s+2Linien mit Linksdrehung in einer einzigen Schleife.

Der Calormen-Interpreter scheint weniger tolerant gegenüber fehlenden Leerzeichen zu sein als zum Zeitpunkt meines ersten Posts, aber der Code unter http://turtleacademy.com/playground/en läuft einwandfrei

Logo, 200 Bytes

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

Dolmetscher unter http://www.calormen.com/jslogo/# Es wird davon ausgegangen, dass die Schildkröte nach Norden zeigt, bevor das Programm ausgeführt wird. Verwenden Sie den csBefehl, um den Bildschirm zu löschen, richten Sie die Schildkröte nach Norden und platzieren Sie sie am Ursprung in der Mitte des Bildschirms.

Bildbeschreibung hier eingeben

Die Grundeinheit aller oben genannten Netze ist ein Paar von Rücken-an-Rücken-Polygonen. Diese sind in 2 versetzten Reihen angeordnet und bilden eine Untereinheit von 4 Polygonen, die vertikal verschoben werden können, um alle Netze zu bilden (mit Ausnahme des Oktaeders, das auf der Zeichnung des Ikosaeders und des Tetraeders reitet). Die Untereinheit bildet 1 Tetraedernetz, 1/5 des Ikosaedernetzes, 1/3 des Dodekaedernetzes und 2/3 des Würfelnetzes (zwei Untereinheiten mit überlappenden mittleren zwei Quadraten).

Ungolfed Code

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
Level River St
quelle
@phase haha, danke, ich habe tatsächlich überlegt ht, es für das Bild zu verstecken. Ich bin froh, dass ich es nicht getan habe!
Level River St