Desenho de redes 3d - sólidos platônicos


14

Esta é uma versão básica das redes 3D de desenho bastante mais difíceis - sólidos arquimedianos .

Eu tenho uma fraqueza pelas redes 3D que, quando cortadas e dobradas, permitem que você faça formas 3D de papel ou cartão. A tarefa é simples: escreva o programa mais curto possível, que desenha redes para os 5 sólidos platônicos. A saída deve ser um arquivo de imagem em qualquer formato sensato de sua escolha (png, jpg, etc.).

Todas as cinco formas são descritas em http://en.wikipedia.org/wiki/Platonic_solid . Suas redes são assim (extraídas de http://www.newscientist.com/gallery/unfolding-the-earth/2 ).

insira a descrição da imagem aqui

Entrada: Um número inteiro de 1 a 5. Suponha que as formas sejam numeradas na ordem do número de lados que possuem. Assim, 1 seria um tetraedro e 5 o icosaedro.

Saída: um arquivo de imagem que contém a rede para essa forma. Apenas o contorno, incluindo as linhas internas, está OK. Não há necessidade de preenchê-lo com cores

Você pode usar qualquer linguagem de programação que desejar, bem como qualquer biblioteca que não tenha sido criada especialmente para esta competição. Ambos devem estar disponíveis gratuitamente no entanto (nos dois sentidos) online.

Aceitarei a resposta com o menor número de caracteres dentro de exatamente uma semana.

Vencedora.Apenas um participante, mas foi maravilhoso. O vencedor é ... Raufio pelo que é meu código favorito de golfe de todos os tempos.

Respostas:


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

Eu implementei um intérprete primitivo com l r f b operadores que movem o cursor da tartaruga no ângulo das formas. Ao mesmo tempo, ele gira apenas um ângulo. Compactei as strings reutilizando strings (como psuedo-sub-rotinas); além disso, não verifiquei se estava usando o melhor caminho. Ele gera um arquivo postscript.

Uma pequena explicação do código não golfe:

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

Importa o módulo embutido tartaruga e define as macros que encurtam as seqüências de caracteres. O módulo tartaruga usa comandos para mover uma 'tartaruga' pela tela (ou seja, para frente (100), esquerda (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 contém os ângulos e as seqüências de movimento. O tetraedro foi salvo para reutilização com os octohedren.

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

Esta é a parte que eu gosto, ela cria funções locais de um único caractere para que as chamadas possam ser encurtadas e automatizadas por meio de strings predefinidas.

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

Isso começa pegando a entrada (entre 1 e 5) e convertendo-a em um índice que aponte para a string de forma no netList. Estes configuração tartaruga para mostrar toda a rede. Eles podem ficar de fora se a tarefa for apenas desenhá-los, mas como precisamos de uma imagem, eles são necessários.

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

O loop for pega os comandos na sequência de sequências de comandos e os executa; portanto, para uma sequência como "fl", executa "forward (angle); left (angle);" chamando as funções locais recém-criadas. a última linha gera um arquivo chamado 'o' que está no formato de postscript usando a função turtle.

Para correr :

Copie-o para um arquivo e execute-o a partir daí. Quando você o executa, ele espera uma entrada de número entre 1 e 5 (eu apenas mudei para que ele pergunte antes de configurar a tartaruga). Quando você digita um número, uma janela é exibida e desenha a rede. se você quiser ir mais rápido, você pode adicionar t.speed(200)antessetup .

Você pode copiar e colar no intérprete, mas quando raw_input()é chamado, consome a próxima string que você digita, em "t.setup(.9,.9)"vez de um número. Então, se você fizer isso, copie atéraw_input() , digite um número e copie e cole o restante. Destina-se a ser executado como um todo. Ou você pode copiá-lo em uma função e chamá-lo.

Aqui estão as saídas (convertidas do postscript):

Nota: a posição destes na janela mudou, mas sua forma geral é a mesma.

tetraedro cubo octaedro dodecaedro icosaedro

É um pouco de força bruta para o código de golfe, mas me cansei de tentar encontrar um padrão consistente entre as formas.


Muito perto. O dodecaedro é definitivamente mais complicado.
felipa 12/02

@ Raufio É muito bom. Não é possível definir um triângulo (ou quadrado ou pentágono) e apenas girá-lo / movê-lo? Ou foi efetivamente o que você fez?
felipa

Efetivamente, sim, foi o que fiz, mas com formas maiores. Por exemplo, o icosaedro é desenhado desenhando dois triângulos, um em cima do outro, e avançando 5 vezes, depois redefinindo em um novo local, desenhando o diamante novamente recuando e repetindo 5 vezes. dé a cadeia que faz os dois triângulos, por isso é(d+'f')*5+setupPosition+(d+'b')*5
Raufio

@ Raufio O código de golfe não funciona para mim. Ele abre uma janela que está quase em branco. Ora, se eu retorno pressione I get p = (ord (raw_input ()) - 49) * 2 TypeError: ord () espera um personagem, mas cadeia de comprimento 0 encontrada
felipa

1
O @felipa setupfaz com que a janela da tartaruga seja grande o suficiente para segurar a rede. O mesmo ocorre com gotoa "tartaruga" para -200, 150. clearlimpa a linha feita por goto. Seus apenas comandos para configurar o desenho. p=(ord(raw_input())-49)*2leva um número, de 1 a 5, correspondente à forma desejada.
Raufio

6

Mathematica

Fora da competição, não é um idioma gratuito (a menos que um teste gratuito conte como gratuito)

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

Uso:

f /@ Range@5

Gráficos do Mathematica


1
O Mathematica definitivamente não é livre em nenhum sentido. Resposta muito boa no entanto.
felipa

@felipa é grátis como na cerveja no Raspberry Pi.
shrx

você sabe, nesse computador livre, o pi framboesa
undergroundmonorail

6

Python 2 (com 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


3

Logotipo, 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

Lendo isso de volta, vejo que minha versão original não estava em conformidade com as especificações escritas (pegue um argumento numérico e desenhe uma forma), mas sim como interpretada por algumas das outras respostas (desenhe todas as formas). A nova versão corrige isso. Ele espera ser chamado como por exemplo q 5.csdeve ser feito antes para limpar a tela e apontar a tartaruga para o norte.

qchama a função principal pcom 3 argumentos. A sintaxe para isso é bastante inchada, então, para superar minha pontuação anterior, tive que raspar bytes em outro lugar.

a nova versão do pleva 3 argumentos. Não há necessidade xe yporque traçamos apenas uma rede, mas do passo entre as subunidades permanece. s ainda é o número de lados por polígono e nagora codifica para duas coisas diferentes> n/8é o número de subunidades a serem plotadas e n*45é um ângulo através do qual a tartaruga deve ser girada antes de começar (aproveitando o mod natural 360 para rotações. )

O loop aprimorado realiza o desenho de slinhas com rotação à direita e s+2linhas com rotação à esquerda em um único loop.

o intérprete calormen parece ser menos tolerante com a falta de espaço em branco agora do que na época do meu primeiro post, mas o código funciona bem em http://turtleacademy.com/playground/en

Logotipo, 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 em http://www.calormen.com/jslogo/# Supõe-se que a tartaruga esteja apontando para o norte antes de o programa ser executado. Use o cscomando para limpar a tela, aponte a tartaruga para o norte e coloque-a na origem no centro da tela.

insira a descrição da imagem aqui

A unidade básica de todas as redes acima é um par de polígonos consecutivos. Estes estão dispostos em 2 fileiras escalonadas, formando uma subunidade de 4 polígonos que podem ser traduzidos verticalmente para formar todas as redes (exceto o octaedro, que monta uma carona no desenho do icosaedro e tetraedro). A subunidade forma 1 rede de tetraedro, 1/5 da rede de icosaedro, 1/3 da rede de dodecaedro e 2/3 da rede de cubos (duas subunidades são desenhadas, com os dois quadrados do meio sobrepostos).

Código ungolfed

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, obrigado, na verdade, considerei fazer um htpara ocultá-lo para a imagem. Estou feliz por não ter!
Level River St
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.