绕轴旋转坐标系

4
我正在将一个形状表示为3D坐标集,我想围绕一个轴旋转整个对象(在此情况下是Z轴,但一旦我使其工作,我想围绕所有三个轴旋转)。
我编写了一些使用旋转矩阵来实现这一点的代码:

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

下面的图像显示了我尝试旋转的对象(沿着Z轴向下看),在尝试旋转之前,每个小球表示我要旋转的一个坐标。 alt text http://www.cs.nott.ac.uk/~jqs/notsquashed.png 以下代码对该对象执行旋转:

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

问题在于我用这种方式进行旋转时,将角度参数设置为(0.0,0.0,1.0)可以运行(有点),但对象会变形,如下所示:

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

这不是我想要的。 有人能告诉我我做错了什么以及如何在不使其变形的情况下绕轴旋转整个对象吗? 谢谢。 nodlams

1
你的旋转代码看起来没问题。不用包装代码试试? - rlbond
我刚刚尝试了一下没有包装代码,不幸的是它没有任何区别。 - JS.
1
我不确定,但在rotate函数的第二个语句中(即pos [1] = ...),您是否使用了pos [0]的更新值。这是有意为之吗? - Ponting
1个回答

7

在rotateByMatrix中进行旋转时,您计算新的pos [0]的位置,但是然后将其输入到计算新的pos [1]的下一行中。因此,您用于计算新pos [1]的pos [0]不是输入,而是输出。请将结果存储在临时变量中并返回。

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;

此外,将pos作为常量引用传递给函数。
const Coord<float> &pos

另外,您应该计算正弦值和余弦值一次,将它们存储在临时变量中并重复使用。


啊,没错,这个可以了。我知道我一定在某个地方犯了一个愚蠢的错误。谢谢你的帮助! - JS.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接