Dibujo de redes 3d - sólidos platónicos

14

Esta es una versión básica de las redes de dibujo en 3D bastante más difíciles : sólidos de Arquímedes .

Tengo una debilidad por las redes 3D que, cuando se recortan y se pliegan, le permiten hacer formas 3D de papel o tarjeta. La tarea es simple, escriba el programa más corto posible que dibuje redes para los 5 sólidos platónicos. El resultado debe ser un archivo de imagen en cualquier formato sensible que elija (png, jpg, etc.).

Las cinco formas se describen en http://en.wikipedia.org/wiki/Platonic_solid . Sus redes se ven así (tomadas de http://www.newscientist.com/gallery/unfolding-the-earth/2 ).

ingrese la descripción de la imagen aquí

Entrada: un entero del 1 al 5. Suponga que las formas están numeradas en orden de la cantidad de lados que tienen. Entonces, 1 sería un tetraedro y 5 el icosaedro.

Salida: un archivo de imagen que contiene la red para esa forma. Solo el esquema que incluye las líneas internas está bien. No es necesario rellenarlo con colores.

Puedes usar cualquier lenguaje de programación que te guste, así como cualquier biblioteca que no haya sido creada especialmente para esta competencia. Sin embargo, ambos deberían estar disponibles gratuitamente (en ambos sentidos) en línea.

Aceptaré la respuesta con el menor número de caracteres en exactamente una semana.

Ganador. Solo un participante pero fue maravilloso. El ganador es ... Raufio por cuál es mi código de golf favorito.

felipa
fuente

Respuestas:

8

Pitón, 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")

Implementé un intérprete primitivo con l r f boperadores que mueven el cursor de la tortuga en el ángulo de las formas. Al mismo tiempo, gira solo un ángulo. Comprimí las cadenas reutilizando cadenas (algo así como las subrutinas psuedo), aparte de eso, no verifiqué si estaba usando la mejor ruta. Sale a un archivo postscript.

Una pequeña explicación del código sin golf:

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

Importa el módulo de tortuga incorporado y define las macros que acortan las cadenas. El módulo de tortuga usa comandos para mover una 'tortuga' por la pantalla (es decir, hacia adelante (100), hacia la izquierda (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
]

Esta lista contiene los ángulos y las secuencias de movimiento. El tetraedro se guardó para reutilizarlo con los octoedros.

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

Esta es la parte que me gusta, realiza funciones locales de un solo carácter para que las llamadas se puedan acortar y automatizar a través de cadenas predefinidas.

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

Esto comienza tomando la entrada (entre 1 y 5) y convirtiéndola en un índice que apunte a la cadena de forma en netList. Estos configuran tortuga para mostrar toda la red. Estos podrían omitirse si la tarea fuera solo dibujarlos, pero dado que necesitamos una salida de imagen, son necesarios.

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

El bucle for toma los comandos en la cadena de secuencia de comandos y los ejecuta, por lo que para una cadena como "fl", ejecuta "adelante (ángulo); izquierda (ángulo);" llamando a las funciones locales recién creadas. la última línea genera un archivo llamado 'o' que está en formato de formato postscript utilizando la función de tortuga.

Para correr :

Cópielo en un archivo y ejecútelo desde allí. Cuando lo ejecute, esperará una entrada de número entre 1 y 5 (simplemente lo cambié para que pregunte antes de configurar la tortuga). Cuando ingresa un número, aparece una ventana emergente y dibuja la red. si quieres que vaya más rápido, puedes agregar t.speed(200)antes setup.

Puede copiarlo y pegarlo en el intérprete, pero cuando raw_input()se lo llama, consume la siguiente cadena que ingresa en "t.setup(.9,.9)"lugar de un número. Entonces, si hace esto, copie hasta raw_input(), ingrese un número, luego copie y pegue el resto. Está destinado a ejecutarse como un todo. O podría copiarlo en una función y llamarlo.

Aquí están sus salidas (convertidas de postscript):

Nota: la posición de estos en la ventana ha cambiado, pero su forma general es la misma.

tetraedro cubo octaedro dodecaedro icosaedro

Es una pequeña fuerza bruta para el golf de código, pero me cansé de tratar de encontrar un patrón consistente entre las formas.

Raufio
fuente
Muy cerca. El dodecaedro es definitivamente más complicado.
felipa
@Raufio Es muy lindo. ¿No es posible definir un triángulo (o cuadrado o pentágono) y luego simplemente rotarlo / moverlo? ¿O es eso efectivamente lo que has hecho?
felipa
Efectivamente, sí, eso es lo que hice, pero con formas más grandes. Por ejemplo, el icosaedro se dibuja dibujando dos triángulos, uno encima del otro, y avanzando 5 veces, luego reiniciando en una nueva ubicación, dibujando el diamante nuevamente moviéndose hacia atrás y repitiendo 5 veces. des la cadena que hace los dos triángulos, así que es(d+'f')*5+setupPosition+(d+'b')*5
Raufio
@Raufio El código de golf no funciona para mí. Abre una ventana que está mayormente en blanco. Si presiono Intro, obtengo p = (ord (raw_input ()) - 49) * 2 TypeError: ord () esperaba un carácter, pero se encontró una cadena de longitud 0
felipa
1
@felipa setuphace que la ventana de la tortuga sea lo suficientemente grande como para sostener la red. Lo mismo con goto, mueve la 'tortuga' a -200, 150. clearborra la línea hecha por goto. Sus justos comandos para configurar el dibujo. p=(ord(raw_input())-49)*2toma un número, del 1 al 5, que corresponde a la forma que desea.
Raufio
6

Mathematica

Fuera de competencia, no es un idioma gratuito (a menos que una prueba gratuita cuente como gratuita)

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

Uso:

f /@ Range@5

Gráficos de Mathematica

Dr. belisario
fuente
1
Mathematica definitivamente no es gratis en ningún sentido. Muy buena respuesta sin embargo.
felipa
@felipa es gratis como en cerveza en la Raspberry Pi.
shrx
ya sabes, en esa computadora libre, la frambuesa pi
undergroundmonorail
6

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

Resultados:

resultados

aditsu renunció porque SE es MALO
fuente
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

Al leer esto, veo que mi versión original no cumplía con la especificación tal como está escrita (toma un argumento numérico y dibuja una forma), sino que es interpretada por algunas de las otras respuestas (dibuja todas las formas). La nueva versión corrige esto. Espera ser llamado como por ejemplo q 5. csdebe hacerse antes para limpiar la pantalla y apuntar la tortuga hacia el norte.

qllama a la función principal pcon 3 argumentos. La sintaxis para esto es bastante hinchada, por lo que para superar mi puntaje anterior tuve que recortar bytes en otros lugares.

La nueva versión de ptoma 3 argumentos. No es necesario xy yporque solo trazamos una red, pero del tono entre subunidades permanece. s sigue siendo el número de lados por polígono, y nahora codifica para dos cosas diferentes> n/8es el número de subunidades que se trazarán, y n*45es un ángulo a través del cual se debe girar la tortuga antes de comenzar (aprovechando el mod 360 natural para las rotaciones. )

El bucle mejorado logra dibujar slíneas con rotación hacia la derecha y s+2líneas con rotación hacia la izquierda en un solo bucle.

el intérprete de calormen parece ser menos tolerante con los espacios en blanco que faltan ahora que en el momento de mi primera publicación, pero el código funciona bien en http://turtleacademy.com/playground/en

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

Intérprete en http://www.calormen.com/jslogo/# Se supone que la tortuga está apuntando hacia el norte antes de ejecutar el programa. Use el cscomando para borrar la pantalla, apunte la tortuga hacia el norte y colóquela en el origen en el centro de la pantalla.

ingrese la descripción de la imagen aquí

La unidad básica de todas las redes anteriores es un par de polígonos consecutivos. Estos se organizan en 2 filas escalonadas, formando una subunidad de 4 polígonos que se pueden traducir verticalmente para hacer todas las redes (excepto el octaedro, que se engancha en el dibujo del icosaedro y el tetraedro). La subunidad forma 1 red de tetraedro, 1/5 de la red de icosaedro, 1/3 de la red de dodecaedro y 2/3 de la red de cubo (se dibujan dos subunidades, con los dos cuadrados centrales superpuestos).

Código sin golf

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
fuente
@phase jaja, gracias, en realidad consideré hacer un htpara ocultarlo para la imagen. ¡Me alegro de no haberlo hecho!
Level River St