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


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.


3

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

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


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


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
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.