2008-11-08 13 views
4

J'écris un programme qui dessine un solide le long de la courbe d'une spline. J'utilise Visual Studio 2005, et j'écris en C++ pour OpenGL. J'utilise FLTK pour ouvrir mes fenêtres (toolkit rapide et léger).Trouver des angles de rotation entre des points 3d

J'ai actuellement un algorithme qui va dessiner une spline cardinale cubique, donné un ensemble de points de contrôle, en séparant les intervalles entre les points en sous-intervalles et en dessinant des segments entre ces sous-points. Le nombre de sous-intervalles est variable. Le code de dessin fonctionne à merveille et fonctionne comme suit: Je génère un ensemble de points le long de la courbe spline en utilisant l'équation de spline et les stocke dans un tableau (comme une structure de données spéciale appelée Pnt3f, où les coordonnées sont 3). flotte et il y a quelques fonctions pratiques telles que la distance, la longueur, le point et le crossproduct). Ensuite, j'ai une seule boucle qui itère à travers le réseau de points et les dessine comme si:

glBegin(GL_LINE_STRIP); 
for(pt = 0; pt<=numsubsegements ; ++pt) { 
    glVertex3fv(pt.v()); 
} 
glEnd(); 

Comme indiqué, ce code fonctionne très bien. Maintenant ce que je veux faire est, au lieu de tracer une ligne, je veux extruder un solide. Mon exploration actuelle utilise un quadricycle 'cylindre' pour créer un tube le long de la ligne. C'est un peu plus compliqué, car je dois orienter openGL dans la direction où je veux dessiner le cylindre. Mon idée est de faire ceci:

psuedocode:

Push the current matrix, 
translate to the first control point 
rotate to face the next point 
draw a cylinder (length = distance between the points) 
Pop the matrix 
repeat 

Mon problème est d'obtenir les angles entre les points. J'ai seulement besoin de lacet et de hauteur, le roulement n'est pas important. Je sais prendre l'arc-cosinus du produit scalaire des deux points divisé par la magnitude des deux points, retournera l'angle entre eux, mais ce n'est pas quelque chose que je peux nourrir à OpenGL pour tourner avec. J'ai essayé de le faire en 2d, en utilisant le plan XZ pour obtenir x rotation, et en faisant les points vecteurs de l'origine, mais cela ne retourne pas l'angle correct.

Mon approche actuelle est beaucoup plus simple. Pour chaque plan de rotation (X et Y), pour l'angle par:

-arc cosinus ((différence de la valeur de 'x')/distance entre les points)

la valeur 'x' dépend de la vous mettez votre avion en place, mais pour mes calculs, j'utilise toujours world x. À moins de quelques problèmes, ce qui fait que je dessine dans le quadrant correct que je n'ai pas encore élaboré, je veux obtenir des conseils pour voir si c'était une bonne implémentation, ou pour voir si quelqu'un savait mieux.

Répondre

1

Vous avez raison de former deux vecteurs à partir des trois points de deux segments de ligne adjacents, puis d'utiliser l'arccosine du produit scalaire pour obtenir l'angle entre eux. Pour utiliser cet angle, vous devez déterminer l'axe autour duquel la rotation doit se produire. Prenez le produit croisé des deux mêmes vecteurs pour obtenir cet axe. Vous pouvez alors build a transformation matrix en utilisant cet angle d'axe ou le transmettre en tant que paramètres à glRotate.

0

Avez-vous considéré gluLookAt? Placez votre point de contrôle en tant que point de vue, le point suivant en tant que point de référence, et faites en sorte que le vecteur ascendant soit perpendiculaire à la différence entre les deux.

+0

Cela ne semble pas fonctionner –

1

Quelques notes:
tout d'abord, ceci:

for(pt = 0; pt<=numsubsegements ; ++pt) { 
    glBegin(GL_LINE_STRIP); 
    glVertex3fv(pt.v()); 
} 
glEnd(); 

est pas une bonne façon de tirer quoi que ce soit. Vous DEVEZ avoir un glEnd() pour chaque glBegin(). vous voulez probablement sortir le glBegin() de la boucle. le fait que cela fonctionne est de la chance pure.

deuxième chose

Mon exploration actuelle utilise un « cylindre » quadrique pour créer un tube le long de la ligne

Cela ne fonctionnera pas comme prévu. la quadrique 'cylindrique' a une base supérieure plate et une base inférieure plate. Même si vous réussissez à faire les rotations correctes en fonction de la spline, les bords des plateaux vont sortir du volume de votre tube prévu et il ne sera pas lisse. Vous pouvez l'essayer en 2D avec juste un stylo et un papier. Essayez de dessiner un tube lisse en utilisant seulement des tubes plus courts avec une base plate. C'est impossible. Troisièmement, à votre vraie question, l'outil définitif pour de telles rotations est quaternions. C'est un peu complexe à expliquer dans ce domaine, mais vous pouvez trouver des informations complètes partout où vous regardez. Si vous avez utilisé QT au lieu de FLTK, vous pouvez également utiliser libQGLViewer. Il a une classe Quaternion intégrée qui vous sauverait la mise en œuvre. Si vous avez encore le choix, je vous recommande fortement de passer à QT.

+0

le glBegin était une faute de frappe. Merci de le saisir. Je l'ai corrigé. –

+0

malheureusement, c'est un pour une classe qui nécessite FLTK. Savez-vous comment dessiner le tube? Je devine que je vais devoir coder le soi quadric comme une sorte de prisme rétangulaire? –