2016-06-22 2 views
2

J'essaie d'apprendre à faire quelques transformations sur des points 3D dans OpenGL. En utilisant this cheat sheet je crois que j'ai la matrice correcte pour multiplier à mon vecteur que je veux faire pivoter. Cependant, quand je multiplie et imprime la nouvelle coord, je crois que c'est incorrect. (Rotating 1,0,0 90deg cc devrait aboutir à 0,1,0 correct?) Pourquoi est-ce ne fonctionne pas?Pourquoi mon vecteur ne tourne-t-il pas correctement OpenGL/GLM?

Mon code:

glm::vec4 vec(1.0f, 0.0f, 0.0f, 1.0f); 
glm::mat4 trans = { 
    1.0f, 0.0f, 0.0f, 0.0f, 
    0.0f, cos(glm::radians(90.0f)), -sin(glm::radians(90.0f)), 0.0f, 
    0.0f, sin(glm::radians(90.0f)), cos(glm::radians(90.0f)), 0, 
    0.0f, 0.0f, 0.0f, 1.0f 
}; 
vec = trans * vec; //I should get 0.0, 1.0, 0.0 right? 
std::cout << vec.x << ", " << vec.y << ", " << vec.z << std::endl; 

Les impressions ci-dessus 1.0, 0.0, 0.0 indiquant qu'il n'y avait pas de changement du tout?

J'ai également essayé d'utiliser la fonction rotate dans GLM pour générer ma matrice plutôt que de spécifier manuellement mais je n'ai toujours pas obtenu ce que je pense être correct (j'ai une autre mauvaise réponse).

glm::mat4 trans = glm::rotate(trans, 90.0f, glm::vec3(0.0, 0.0, 1.0)); //EDIT: my bad, should've been z axis not x, still not working 

Les impressions ci-dessus: -2.14..e+08, -2.14..e+08, -2.14..e+08

(PS: Je viens de prendre la géométrie dans l'année scolaire précédente, mes excuses si le calcul est incorrect, j'ai une compréhension de base des matrices et la multiplication de matrices que je cueillis. jusqu'à aujourd'hui pour apprendre les transformations OpenGL mais d'autres que je suis un peu à ça)

+0

Si l'entrée est (1,0,0,1) et la sortie doit être (0,1,0,1), vous devez tourner autour de l'axe Z. –

+0

@HannesHauptmann ok, j'ai essayé de faire ce changement, mais il ne renvoie toujours pas la bonne réponse 'glm :: mat4 trans = glm :: rotate (trans, 90.0f, glm :: vec3 (0.0, 0.0, 1.0)) ; ' –

+0

Sur le côté gauche, vous voyez comment OpenGL le gère. Je suis 100% c'est une rotation autour de l'axe Z :) –

Répondre

4

Dans votre code, vous êtes en rotation un vecteur unitaire sur l'axe x autour de l'axe des x et qui ne change pas le vecteur (imaginez tourner un crayon autour de lui-même, la direction ne change pas tout).

Pour obtenir ce que vous vouliez précédemment, vous devez tourner le vecteur autour de l'axe z en utilisant la matrice comme ceci:

glm::mat4 trans = { 
    cos(glm::radians(90.0f)), -sin(glm::radians(90.0f)), 0.0f, 0.0f, 
    sin(glm::radians(90.0f)), cos(glm::radians(90.0f)), 0.0f, 0.0f, 
    0.0f, 0.0f, 1.0f, 0.0f, 
    0.0f, 0.0f, 0.0f, 1.0f 
}; 

En outre, glm::mat4 trans = glm::rotate(trans, 90.0f, glm::vec3(0.0, 0.0, 1.0)); ne retourne pas le résultat souhaité parce que le besoin trans être initialisé avant de le passer à glm :: rotate. Essayez d'écrire comme ceci:

glm::mat4 trans; // Default constructor called, trans is an identity matrix 
trans = glm::rotate(trans, glm::radians(90.0f), glm::vec3(0.0, 0.0, 1.0)); 

Pourtant, vous ne pouvez pas obtenir le vecteur attendu (0.0f, 1.0f, 0.0f) en raison de la perte de précision lors de l'utilisation GLM :: radians et cos/sen. Dans mon test, j'ai obtenu le vecteur (-4.37113883e-008f, 1.0f, 0.0f) et -4.37113883e-008 est vraiment -0.0000000437113883 qui est un nombre très proche de 0, le résultat attendu.

+0

Ah merci Jean. C'est aussi ce que me disait @HannesHauptmann. –

+0

Je pense que la raison pour laquelle j'ai été confondu avec la commande rotate() est que je suis habitué à Java. Je ne me suis pas rendu compte que mat4 était un obj (parce qu'il ne commence pas w/capital) et aussi je n'ai jamais réalisé qu'il était initialisé avec un constructeur (car en Java vous utiliseriez new et ensuite appelez explicitement constructeur). Voir, c'est pourquoi C++ me confond lol –

2

La raison pour laquelle votre propre matrice de rotation ne change pas l'entrée est simple: votre rotation n'affecte que les coordonnées y et z et puisque sont zéro le résultat est exactement le même que l'entrée. La coordonnée X a un multiplicateur de 1 dans la coordonnée de sortie x de sorte que cela reste le même.

Vous pouvez créer le vecteur 1.0, 2.0, 3.0, 1.0 par exemple, puis vous verrez les modifications. Quant à la version glm, je ne peux pas dire pourquoi cela donnerait un résultat étrange, je n'ai jamais eu de problèmes avec eux mais je n'ai pas beaucoup utilisé.

+0

Merci pour la réponse rapide Sami. +1 parce que cela a aidé. J'accepte Jean parce qu'il contient plus d'informations (explique pourquoi la commande 'rotate()') ne fonctionne pas. J'espère que cela ne vous dérange pas. –