2009-11-07 3 views
4

Je représente une forme comme un ensemble de coordonnées en 3D, j'essaie de faire pivoter l'objet entier autour d'un axe (dans ce cas, l'axe Z, mais je voudrais tourner autour tous les trois une fois que je l'ai fait fonctionner).Rotation des coordonnées autour d'un axe

J'ai écrit un code pour le faire en utilisant une matrice de rotation:


//Coord is a 3D vector of floats 
//pos is a coordinate 
//angles is a 3d vector, each component is the angle of rotation around the component axis 
//in radians 
Coord<float> Polymers::rotateByMatrix(Coord<float> pos, const Coord<float> &angles) 
{ 
    float xrot = angles[0]; 
    float yrot = angles[1]; 
    float zrot = angles[2]; 

    //z axis rotation 
    pos[0] = (cosf(zrot) * pos[0] - (sinf(zrot) * pos[1])); 
    pos[1] = (sinf(zrot) * pos[0] + cosf(zrot) * pos[1]); 

    return pos; 
} 

L'image ci-dessous montre l'objet que je suis en train de tourner (regardant vers le bas l'axe Z) avant que la rotation est tentée, chaque petite sphère indique l'une des coordonnées que je suis en train de tourner

alt text http://www.cs.nott.ac.uk/~jqs/notsquashed.png

la rotation est effectuée pour l'objet par le code suivant:


//loop over each coordinate in the object 
for (int k=start; k<finish; ++k) 
{ 
    Coord<float> pos = mp[k-start]; 
    //move object away from origin to test rotation around origin 
    pos += Coord<float>(5.0,5.0,5.0); 

    pos = rotateByMatrix(pos, rots); 

    //wrap particle position 
    //these bits of code just wrap the coordinates around if the are 
    //outside of the volume, and write the results to the positions 
    //array and so shouldn't affect the rotation. 
    for (int l=0; l<3; ++l) 
    { 
     //wrap to ensure torroidal space 
     if (pos[l] < origin[l]) pos[l] += dims[l]; 
     if (pos[l] >= (origin[l] + dims[l])) pos[l] -= dims[l]; 

     parts->m_hPos[k * 4 + l] = pos[l]; 
    } 
} 

Le problème est que lorsque je joue la rotation de cette façon, avec les angles jeu de paramètres (0.0,0.0,1.0), il fonctionne (en quelque sorte), mais l'objet se déforme, comme ceci:

alt text http://www.cs.nott.ac.uk/~jqs/squashed.png

ce qui n'est pas ce que je veux. Quelqu'un peut-il me dire ce que je fais mal et comment je peux faire pivoter l'objet entier autour de l'axe sans le déformer?

Merci

nodlams

+1

Votre code de rotation semble correct. Essayez-le sans votre code wrap? – rlbond

+0

Je viens de l'essayer sans le code de retour, malheureusement cela n'a pas fait de différence. –

+1

Je ne suis pas sûr ... mais dans la deuxième instruction de la fonction de rotation (c'est-à-dire pos [1] = ...) vous utilisez la valeur mise à jour de pos [0]. Est-ce que c'est prévu? – Ponting

Répondre

7

Où que vous faites votre rotation rotateByMatrix, vous calculer les nouveaux pos [0], mais qui se nourrissent dans la ligne suivante pour calculer les nouveaux pos [1]. Donc le pos [0] que vous utilisez pour calculer le nouveau pos [1] n'est pas l'entrée, mais la sortie. Stockez le résultat dans une variable temp et renvoyez-le.

Coord<float> tmp; 
tmp[0] = (cosf(zrot) * pos[0] - (sinf(zrot) * pos[1])); 
tmp[1] = (sinf(zrot) * pos[0] + cosf(zrot) * pos[1]); 
return tmp; 

De même, passez le pos dans la fonction en tant que référence const. De plus, vous devez calculer les valeurs de sin et de cos une fois, les stocker temporairement et les réutiliser.

+0

Ah oui, ça marche, je suis nouveau J'ai dû faire une erreur stupide quelque part. Merci de votre aide! –