4
votes

I'm representing a shape as a set of coordinates in 3D, I'm trying to rotate the whole object around an axis (In this case the Z axis, but I'd like to rotate around all three once I get it working).

I've written some code to do this using a rotation matrix:


//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;
}

The image below shows the object I'm trying to rotate (looking down the Z axis) before the rotation is attempted, each small sphere indicates one of the coordinates I'm trying to rotate

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

The rotation is performed for the object by the following code:


//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];
    }
}

The problem is that when I perform the rotation in this way, with the angles parameter set to (0.0,0.0,1.0) it works (sort of), but the object gets deformed, like so:

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

which is not what I want. Can anyone tell me what I'm doing wrong and how I can rotate the entire object around the axis without deforming it?

Thanks

nodlams

1
Your rotation code looks right. Try it without your wrap code?rlbond
I just tried it without the wrap code, unfortunately it didn't make a difference.JS.
I am not sure..but in the second statement in the rotate function (i.e. pos[1]= ...) you are using the updated value of pos[0]. Is that intended?Ponting

1 Answers

7
votes

Where you do your rotation in rotateByMatrix, you compute the new pos[0], but then feed that into the next line for computing the new pos[1]. So the pos[0] you're using to compute the new pos[1] is not the input, but the output. Store the result in a temp var and return that.

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;

Also, pass the pos into the function as a const reference.

const Coord<float> &pos

Plus you should compute the sin and cos values once, store them in temporaries and reuse them.