Desenhe um cubo simples

10

Não temos um único desafio em desenhar um cubo tridimensional real, então aqui vai:

Desafio

Sua tarefa é desenhar um cubo girado com perspectiva. Pode estar em uma janela separada ou como uma imagem.

Entrada

Sua entrada é 3 números separados entre 0 e 359,99 ... Eles representam a rotação em torno dos eixos x, ye z em graus.

0 0 0
30 0 40
95 320 12

Resultado

Você pode exibi-lo em uma janela separada ou salvar uma imagem. Você pode usar qualquer tipo de exibição (baseada em vetor, rasterizada etc.).

Edit: ASCII também é permitido, para permitir idiomas de golfe com apenas saída de texto.

A saída para gráficos rasterizados ou ASCII deve ser de pelo menos 50 * 50 (pixels para rasterização, caracteres para ASCII)

Informação adicional

O eixo z positivo aponta para fora da janela, o eixo x é horizontal e o eixo y é vertical. Basicamente, o padrão OpenGL.

As rotações são no sentido anti-horário se você olhar o cubo na direção negativa de um eixo específico, por exemplo, olhando para o eixo y.

A câmera deve estar no eixo z a uma distância razoável do cubo na direção z negativa, o cubo deve estar em (0; 0; 0). O. O cubo também precisa estar totalmente visível e ocupar pelo menos 50% da moldura de desenho. A câmera deve olhar na direção z positiva no cubo.

As rotações do cubo são aplicadas na ordem x-> y-> z.

O cubo é girado em torno de seu centro, não se move.

Para projetar um cubo no espaço 2D, é necessário dividir as coordenadas xey do cubo com a distância paralela ao eixo z entre o ponto e a câmera.

Regras

Bibliotecas de renderização são permitidas, mas os vértices precisam ser definidos no código. Nenhuma classe de modelo de cubo 3d.

Casos de teste

insira a descrição da imagem aqui

Bálint
fonte
11
Tem que ser wireframe?
Rɪᴋᴇʀ
Importa-se de incluir um algoritmo para os pontos?
Leaky Nun
3
Em que ordem / direção são feitas as rotações? De onde a câmera está olhando? Que tipo de projeção temos que usar?
flawr
6
Mas como eu disse, as rotações não darão certo. Como você o definiu agora, o cubo será movido para fora do campo de visão se, por exemplo, girado em torno do eixo x. Por favor, use a caixa de areia .
flawr
6
@ EᴀsᴛᴇʀʟʏIʀᴋ google will tell you the formula. Não , os desafios devem conter o máximo possível de material e informações necessárias para resolvê-los, incluídos no corpo do post . Eu não deveria ter que pesquisar no Google ou pesquisar na Wikipedia apenas para começar a entender.
gato

Respostas:

2

Shoes (rubi) 235 231

Tudo computado do zero.

Shoes.app{p,a,b,c=ARGV.map{|j|j.to_f/90}
k=1+i="i".to_c
p=(0..3).map{|j|y,z=(k*i**(j+a)).rect
x,z=(((-1)**j+z*i)*i**b).rect
q=(x+y*i)*i**c
[90*(k+q/(z-4)),90*(k+q/(4+z))]}
4.upto(15){|j|line *(p[j%4][0].rect+p[(j+j/4)%4][1].rect)}}

Ligar da linha de comando, por exemplo shoes cube3d.rb 0 30 0

A idéia é gerar / girar simultaneamente os quatro vértices de um tetraedro em 3d. Então, como estes são reduzidos a 2d, geramos os quatro vértices do tetraedro inverso (o total de 8 vértices são os do cubo.) Isso fornece 4 pares de vértices correspondentes às 4 diagonais do corpo. Finalmente, os 2d vértices são conectados por linhas: cada vértice do tetraedro original deve ser conectado a cada vértice do tetraedro inverso, formando as 12 arestas e as 4 diagonais do corpo do cubo. A ordem garante que as diagonais do corpo não sejam plotadas.

Saída de casos de teste

Observe que, para ser consistente com os dois últimos casos de teste, a rotação em torno do eixo z é no sentido horário a partir do ponto de vista do visualizador. No entanto, isso parece estar em contradição com as especificações. A direção da rotação pode ser revertida modificando *i**c->/i**c

insira a descrição da imagem aqui

destroçado

Shoes.app{
  p,a,b,c=ARGV.map{|j|j.to_f/90}   #Throw away first argument (script name) and translate next three to fractions of a right angle.
  k=1+i="i".to_c                   #set up constants i=sqrt(-1) and k=1+i

  p=(0..3).map{|j|                 #build an array p of 4 elements (each element wil be a 2-element array containing the ends of a body diagonal in complex number format)
    y,z=(k*i**(j+a)).rect          #generate 4 sides of square: 1+i,i-1,-1-i,-i+1, rotate about x axis by a, and store in y and z as reals 
    x,z=(((-1)**j+z*i)*i**b).rect  #generate x axis displacements 1,-1,1,-1, rotate x and z about y axis by b, store in x and z as reals
    q=(x+y*i)*i**c                 #rotate x and y about z axis, store result in q as complex number
  [90*(k+q/(z-4)),90*(k+q/(4+z))]} #generate "far" vertex q/(4+z) and "near" vertex q/-(4-z) opposite ends of body diagonal in 2d format.

  4.upto(15){|j|                   #iterate through 12 edges, use rect and + to convert the two complex numbers into a 4 element array for line method
    line *(p[j%4][0].rect+         #cycle through 4 vertices of the "normal" tetrahedron
     p[(j+j/4)%4][1].rect)         #draw to three vertices of the "inverted" tetrahedron. j/4=1,2,3, never 0
  }                                #so the three edges are drawn but the body diagonal is not.
}

Observe que, por razões históricas, um fator de escala de 90 é aplicado na linha 9 (escolhido como o mesmo que 90 graus na linha 2 para o golfe), mas no final não havia vantagem no uso desse valor em particular, então ele se tornou um fator de escala. escolha arbitrária.

Level River St
fonte
3

HTML / CSS / JS, 739 bytes, provavelmente não concorrente

Mas eu só queria mostrar as transformações CSS 3D.

Neil
fonte
Isso realmente parece bem arrumado. Eu experimentei transformações CSS3 antes, mas tive problemas com isso.
Bálint 29/04
Você parece ter as rotações na ordem errada. Deve ser x então y então z. Você tem z então y então x. @ Bálint pode confirmar.
Level River St
@LevelRiverSt Quando escrevi isso, não sabia qual deveria ser o pedido e não consegui resolver isso nos casos de teste, então obrigado por me atualizar. Também mudei a direção da rotação X, então agora eu combino todos os casos de teste.
29416 Neil
Você ainda pode fornecer uma contagem de bytes? Mesmo se as respostas não são concorrentes devem sempre ter uma contagem de bytes
Downgoat
@Downgoat Jogou golfe ou não?
Neil
0

Maple, 130 + 14 (em andamento)

with(plots):f:=(X,Y,Z)->plot3d(0,x=0..1,y=0..1,style=contour,tickmarks=[0,0,0],labels=["","",""],axes=boxed,orientation=[Z,-X,Y]);

insira a descrição da imagem aqui

Isso cria uma função constante dentro de uma caixa e, em seguida, usa opções de plotagem para ocultar marcações, rótulos e a própria função. A adição projection=.5das opções aproxima a câmera, permitindo a visualização em perspectiva.
Eu escrevi isso antes das especificações serem finalizadas e a ordem de rotação é em x, y', z''vez de x, y, z. Até eu corrigir os ângulos, aqui está outra solução

POV-Ray, 182

#include"a.txt"
#include"shapes.inc"
camera{location 9*z look_at 0}
light_source{9*z color 1}
object{Wire_Box(<-2,-2,-2>,<2,2,2>,.01,0)texture{pigment{color rgb 1}}rotate<R.x,-R.y,-R.z>}

lê a entrada através do a.txtarquivo que deve conter
#declare R=<xx,yy,zz>;
com xx,yy,zzsendo os ângulos de rotação

insira a descrição da imagem aqui

DenDenDo
fonte
11
Yay por usar o POV-ray, é um ótimo programa. Infelizmente, as regras agora declaram que nenhuma classe de cubo 3d pode ser usada.
miles