Tourner en 3D - Point autour d'une autre
J'ai une fonction dans mon programme qui tourne un point (x_p, y_p, z_p) autour d'un autre point (x_m, y_m, z_m) par les angles w_nx & w_ny. Les nouvelles coordonnées sont stockées dans des variables globales x_n, y_n, et z_n. La Rotation autour de l'axe des y (donc évolution de la valeur de w_nx - de sorte que les valeurs de y sont pas endommagés) fonctionne correctement, mais dès que je fais une rotation autour de l'x ou l'axe z (la modification de la valeur de w_ny) les coordonnées ne sont pas plus valables. J'ai commenté sur la ligne je pense que mon erreur est, mais je n'arrive pas à comprendre quel est le problème avec ce code.
Quelqu'un peut m'aider?
void rotate(float x_m, float y_m, float z_m, float x_p, float y_p, float z_p, float w_nx ,float w_ny)
{
float z_b = z_p - z_m;
float x_b = x_p - x_m;
float y_b = y_p - y_m;
float length_ = sqrt((z_b*z_b)+(x_b*x_b)+(y_b*y_b));
float w_bx = asin(z_b/sqrt((x_b*x_b)+(z_b*z_b))) + w_nx;
float w_by = asin(x_b/sqrt((x_b*x_b)+(y_b*y_b))) + w_ny; //<- there must be that fault
x_n = cos(w_bx)*sin(w_by)*length_+x_m;
z_n = sin(w_bx)*sin(w_by)*length_+z_m;
y_n = cos(w_by)*length_+y_m;
}
- Si votre aide opengl je suis sûr que d'une bibliothèque graphique aurait une matrice de vecteurs et de l'implantation que vous pouvez utiliser. la rotation d'un point par l'intermédiaire d'une matrice de simplification de votre algorithme.
- Vouliez-vous dire "mise en œuvre"? 😉
- Si vous n'êtes pas déjà familier avec le terme, vous devriez lire sur "Gimbal Lock". Je ne peux pas dire immédiatement si votre code pourrait en souffrir, mais c'est un défaut commun quand vous faites ce genre de rotation à l'aide de "Angles d'Euler".
- j'ai essayé d'utiliser
glrotatef
, mais il ne tourne que le dessin, pas les coordonnées des sommets, et j'ai besoin de faire tourner les coordonnées afin de vérifier les collisions!
Vous devez vous connecter pour publier un commentaire.
Ce que le code ne fait presque:
Il y a deux problèmes:
Donc dans ce cas à l'aide de la matrice et vecteur de mathématiques pour vous aider:
de base des matrices de rotation.
Essayez d'utiliser le vecteur de mathématiques. décider dans quel ordre vous les faire pivoter, d'abord le long de x, puis le long de y peut-être.
Si vous faites pivoter le long de z [z' = z]
La même répété pour l'axe y: [y" = y']
De nouveau en rotation le long de l'axe des x: [x"' = x"]
Et enfin, la question de la rotation autour de quelques "point":
Première soustraire le point à partir des coordonnées, puis appliquer les rotations et enfin ajouter le point de retour pour la suite.
Le problème, autant que je le vois, est un proche parent de "gimbal lock". L'angle w_ny ne peut pas être mesurée par rapport à l'fixe xyz -le système de coordonnées, mais le système de coordonnées qui est mis en rotation par l'application de l'angle w_nx.
Comme kakTuZ observé, votre code convertit point de coordonnées sphériques. Il n'y a rien d'intrinsèquement mauvais avec qui -- de longitude et de latitude, on peut atteindre tous les endroits de la Terre. Et si l'on ne se soucie pas de l'inclinaison du plan équatorial de la Terre par rapport à sa trajectoire autour du Soleil, c'est ok avec moi.
Le résultat de la rotation de la prochaine axe de référence le long de la première w_ny est que les deux points qui sont à 1 km d'une partie de l'autre à l'équateur, à se rapprocher les uns des autres au niveau des pôles et à la latitude de 90 degrés, qu'ils touchent. Même si le but apparent est de les garder 1 km de distance où ils sont en rotation.
y''
?z'=z
,y''=y'
,x'''=x''
manquant. Les trois calculs sont la matrice des multiplications avec des "matrices de rotation".x=f(x,y); y=f(x,y);
quand ces fonctions doivent être exercées simultanément, comme illustré par le choix des paramètres ici:x'= f(x,y); y' = f(x,y);
La notation x-prime résout le problème de mauvais résultats intermédiaires.z'' = z'*sin b + x' * cos b;
->z'' = x'*sin b + z' * cos b;
etz''' = z'' * sin c + y'' * cos c
->z''' = y'' * sin c + z'' * cos c
. Est-il logique?si vous voulez transformer les systèmes de coordonnées plutôt que des points que vous avez besoin de 3 angles. Mais vous avez raison - pour transformer les points 2 angles de vue sont assez. Pour plus de détails demandez Wikipédia ...
Mais quand vous travaillez avec opengl, vous devriez vraiment utiliser les fonctions opengl comme
glRotatef
. Ces fonctions seront calculés sur le GPU, pas sur le PROCESSEUR de votre fonction. La doc est ici.glrotatef
, mais il ne tourne que le dessin, pas les coordonnées, et j'ai besoin de faire tourner les coordonnées afin de vérifier les collisionsComme beaucoup d'autres l'ont dit, vous devez utiliser glRotatef pour la faire tourner pour le rendu. Pour la collision de la manipulation, vous pouvez obtenir son espace-monde de la position en multipliant son vecteur position par l'OpenGL de la matrice ModelView en haut de la pile au moment de son rendu. Obtenir cette matrice avec glGetFloatv, puis de le multiplier avec votre propre vecteur-matrice de la multiplication d'une fonction, ou utiliser l'un des nombreux ceux que vous pouvez obtenir facilement en ligne.
Mais, que serait une douleur! Au lieu de cela, regarder dans l'aide de la GL de la rétroaction de la mémoire tampon. Ce tampon sera tout simplement stocker les points où la primitive aurait été dessiné au lieu de réellement le dessin primitif, et puis vous pouvez y accéder à partir de là.
Cette est un bon point de départ.