2015-04-06 5 views
1

Je crée par programmation des fichiers dans VRML 2.0. J'ai besoin de construire un cylindre qui a son fond à l'origine et son sommet à une coordonnée donnée, mais j'ai quelques problèmes pour déterminer la rotation. Je l'ai googlé, mais la documentation sur VRML 2.0 semble être très rare.Comment créer un cylindre entre l'origine et certaines coordonnées en VRML

Je supposais que spherical coordinates fonctionnerait mieux pour ce que j'essaie de faire, donc j'ai calculé les coordonnées sphériques (r, theta, phi) pour le point cible (x, y, z). J'ai ensuite créé le fichier ci-dessous.

#VRML V2.0 utf8 

DEF v1 Transform { 
    translation 0 0 0 
    children Shape { 
     geometry Sphere {radius .5} 
    } 
} 
DEF v2 Transform { 
    translation x y z 
    children Shape { 
     geometry Sphere {radius .5} 
    } 
} 
DEF edge Transform { 
    translation 0 0 0 
    children Transform { 
     rotation 0 1 0 theta-pi/2 
     children Transform { 
      rotation 0 0 1 phi-pi/2 
      children Transform { 
       translation 0 r/2 0 
       children Shape { 
        geometry Cylinder { 
         radius .08 
         height r 
        } 
       } 
      } 
     } 
    } 
} 

Et voici une version avec certaines valeurs par exemple:

#VRML V2.0 utf8 

DEF v1 Transform { 
    translation 0 0 0 
    children Shape { 
     geometry Sphere {radius .5} 
    } 
} 
DEF v2 Transform { 
    translation 4 3 3 
    children Shape { 
     geometry Sphere {radius .5} 
    } 
} 
DEF edge Transform { 
    translation 0 0 0 
    children Transform { 
     rotation 0 1 0 -0.54041949679 
     children Transform { 
      rotation 0 0 1 -0.92729521779 
      children Transform { 
       translation 0 2.915475947 0 
       children Shape { 
        geometry Cylinder { 
         radius .08 
         height 5.830951895 
        } 
       } 
      } 
     } 
    } 
} 

Si vous affichez ce dernier fichier, vous verrez que le cylindre est en fait assez proche, mais pas tout à fait encore.

+0

Le nœud du cylindre n'est-il pas par défaut CENTRE sur l'origine? Si vous voulez que la base soit à l'origine, vous devez la traduire par la moitié de la hauteur. Aussi, est-ce que la hauteur du cylindre est calculée en fonction de l'endroit où vous voulez que le sommet soit, et le point est-il en haut du milieu du sommet? Il existe de bonnes références sur http://graphcomp.com/info/specs/sgi/vrml/spec/ et http://accad.osu.edu/~pgerstma/class/vnv/resources/info/AnnotatedVrmlRef/Book. html – ViennaMike

+0

Le cylindre est en effet centré sur l'origine, mais j'ai déjà traduit, donc ce n'est pas le problème. La traduction est la septième ligne du bord DEF. Le point pour le haut est en effet le milieu. Je connaissais la première référence, mais elle est très vague sur les spécificités de la rotation. La deuxième référence est nouvelle pour moi, et je vais y jeter un coup d'oeil. – user3031033

Répondre

1

O.K., il ya longtemps que j'ai fait ce genre de choses, mais je pense que j'ai compris pourquoi votre approche ne fonctionne pas et comment le faire. Le calcul en utilisant des coordonnées sphériques, comme vous l'avez essayé, provient d'un cadre de référence FIXE qui ne tourne pas lui-même. Mais une fois que vous avez pivoté autour de y dans votre code en VRML, l'axe z n'est plus pointé là où il l'avait été, mais il l'a également fait pivoter. Votre cadre de référence a changé. Maintenant, une approche consiste à utiliser les angles d'Euler et les multiples rotations x, y et z, mais vous devriez être capable de faire une seule rotation une fois que vous avez trouvé le quaternion (qui représente les coordonnées x, y et z de un vecteur de rotation et la quantité de rotation). Voir this Q&A d'où vient la formule. Vous souhaitez que l'axe Y réorienté dans le système de coordonnées du cylindre s'aligne sur un vecteur de l'origine à la coordonnée donnée. Vous voulez donc qu'une rotation déplace le point 0, r, 0 vers le nouveau x, y, z. Voici comment faire:

  1. v1 est 0, r, 0 (r est la hauteur du cylindre)
  2. v2 est les coordonnées où vous voulez que le centre de la partie supérieure pour être
  3. vecteur a = produit croisé (v1, v2)
  4. Normaliser le vecteur a. La spécification VRML. dit qu'il attend un vecteur de rotation normalisé, donc mieux vaut prévenir que guérir. Pour normaliser, calculez la longueur du vecteur a puis divisez les composantes x, y et z par la longueur.
  5. Angle de rotation est la longueur (v1) * longueur (v2) + dotProduct (v1, v2)
  6. Vous avez juste besoin d'une seule transformation de rotation, où vous utilisez les x, y, et les valeurs de z pour la normalisée vecteur calculé à l'étape 4 et l'angle calculé à l'étape 5.