Dessinez un cube simple

10

Nous n'avons pas un seul défi à dessiner un vrai cube en 3 dimensions, alors voici:

Défi

Votre tâche consiste à dessiner un cube en rotation avec perspective. Il peut être dans une fenêtre séparée ou sous forme d'image.

Contribution

Votre entrée est composée de 3 nombres séparés entre 0 et 359,99 ... Ceux-ci représentent la rotation autour des axes x, y et z en degrés.

0 0 0
30 0 40
95 320 12

Production

Vous pouvez soit l'afficher dans une fenêtre séparée, soit enregistrer une image. Vous pouvez utiliser n'importe quel type d'affichage (vectoriel, tramé, etc.).

Edit: ASCII est également autorisé, pour autoriser les langues de golf avec uniquement une sortie textuelle.

La sortie pour les graphiques tramés ou ASCII doit être d'au moins 50 * 50 (pixels pour la pixellisation, caractères pour ASCII)

Information additionnelle

L'axe z positif pointe vers la fenêtre, l'axe x est horizontal et l'axe y est vertical. Fondamentalement, la norme OpenGL.

Les rotations sont dans le sens antihoraire si vous regardez le cube dans le sens négatif d'un axe spécifique, par exemple en regardant vers le bas pour l'axe y.

La caméra doit être sur l'axe z à une distance raisonnable du cube dans la direction z négative, le cube doit être à (0; 0; 0). Le. le cube doit également être entièrement visible et occuper au moins 50% du cadre de dessin. La caméra doit regarder dans le sens z positif au cube.

Les rotations du cube sont appliquées dans l'ordre x-> y-> z.

Le cube tourne autour de son centre, il ne bouge pas.

Pour projeter un cube dans un espace 2D, vous devez diviser les coordonnées x et y du cube avec la distance parallèle à l'axe z entre le point et la caméra.

Règles

Les bibliothèques de rendu sont autorisées, mais les sommets doivent être définis dans le code. Aucune classe de modèle de cube 3D.

Cas de test

entrez la description de l'image ici

Bálint
la source
1
Doit-il être filaire?
Rɪᴋᴇʀ
Voulez-vous inclure un algorithme pour les points?
Leaky Nun
3
Dans quel ordre / directions les rotations sont-elles effectuées? D'où la caméra regarde-t-elle? Quel type de projection devons-nous utiliser?
flawr
6
Mais comme je l'ai dit, les rotations ne fonctionneront pas. Comme vous l'avez défini maintenant, le cube sera déplacé hors du champ de vision s'il tourne par exemple autour de l'axe x. Veuillez utiliser le bac à sable .
flawr
6
@ EᴀsᴛᴇʀʟʏIʀᴋ google will tell you the formula. Non , les défis doivent contenir autant de matériel et d'informations nécessaires pour les résoudre que possible, inclus dans le corps du message . Je ne devrais pas avoir à aller sur Google ou sur Wikipedia pour commencer à comprendre.
chat

Réponses:

2

Chaussures (Ruby) 235 231

Tout est calculé à partir de zéro.

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

Appel depuis la ligne de commande, par exemple shoes cube3d.rb 0 30 0

L'idée est de générer / faire tourner simultanément les quatre sommets d'un tétraèdre en 3D. Puis, comme ceux-ci sont réduits à 2d, nous générons les quatre sommets du tétraèdre inverse (le total des 8 sommets étant ceux du cube). Cela donne 4 paires de sommets correspondant aux 4 diagonales du corps. Enfin les 2d sommets sont reliés par des lignes: chaque sommet du tétraèdre d'origine doit être connecté à chaque sommet du tétraèdre inverse formant les 12 arêtes et 4 diagonales du corps du cube. La commande garantit que les diagonales du corps ne sont pas tracées.

Sortie des cas de test

Notez que, pour être cohérent avec les deux derniers cas de test, la rotation autour de l'axe z est dans le sens horaire à partir du PDV du visualiseur. Cela semble cependant être en contradiction avec la spécification. Le sens de rotation peut être inversé en modifiant *i**c->/i**c

entrez la description de l'image ici

non golfé

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

Notez que pour des raisons historiques, un facteur d'échelle de 90 est appliqué dans la ligne 9 (choisi pour être identique à 90 degrés dans la ligne 2 pour le golf) mais en fin de compte, il n'y avait aucun avantage au golf à utiliser cette valeur particulière, il est donc devenu un choix arbitraire.

Level River St
la source
3

HTML / CSS / JS, 739 octets, probablement non concurrents

Mais je voulais juste montrer les transformations CSS 3D.

Neil
la source
Cela semble en fait assez soigné. J'ai déjà expérimenté des transformations CSS3, mais j'ai eu des problèmes avec.
Bálint
Vous semblez avoir les rotations dans le mauvais ordre. Ce doit être x puis y puis z. Vous avez z puis y puis x. @ Bálint peut confirmer.
Level River St
@LevelRiverSt Quand j'ai écrit ceci, je ne savais pas quelle devrait être la commande, et je n'ai pas pu le calculer à partir des cas de test, alors merci de m'avoir mis à jour. J'ai également inversé le sens de la rotation X, alors maintenant je fais correspondre tous les cas de test.
Neil
Pouvez-vous toujours fournir un nombre d'octets? Même si les réponses ne sont pas en concurrence, elles devraient toujours avoir un nombre d'octets
Downgoat
@Downgoat Golfé ou non-golfé?
Neil
0

Érable, 130 + 14 (en cours)

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]);

entrez la description de l'image ici

Cela trace une fonction constante à l'intérieur d'une boîte, puis utilise des options de tracé pour masquer les graduations, les étiquettes et la fonction elle-même. L'ajout projection=.5aux options rapproche la caméra, permettant une vue en perspective.
J'ai écrit ceci avant que les spécifications ne soient finalisées et l'ordre de rotation est à la x, y', z''place de x, y, z. Jusqu'à ce que je fixe les angles, voici une autre solution

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

lit l'entrée dans le a.txtfichier qui doit contenir
#declare R=<xx,yy,zz>;
avec xx,yy,zzles angles de rotation

entrez la description de l'image ici

DenDenDo
la source
1
Oui pour utiliser POV-ray, c'est un excellent programme. Malheureusement, les règles stipulent désormais qu'aucune classe de cube 3D ne peut être utilisée.
miles