【问题标题】:Rotating coordinates around an axis绕轴旋转坐标
【发布时间】:2009-11-07 18:56:46
【问题描述】:

我将一个形状表示为 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

这不是我想要的。谁能告诉我我做错了什么以及如何在不变形的情况下围绕轴旋转整个对象?

谢谢

诺德兰

【问题讨论】:

  • 您的轮换代码看起来正确。不使用包装代码试试?
  • 我只是在没有包装代码的情况下尝试了它,不幸的是它没有任何区别。
  • 我不确定..但是在旋转函数的第二个语句(即 pos[1]= ...)中,您使用的是 pos[0] 的更新值。这是故意的吗?

标签: c++ math graphics rotation


【解决方案1】:

在 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 引用传递给函数。

const Coord<float> &pos

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

【讨论】:

  • 嗯,这行得通,我是新手,我一定在某个地方犯了一些愚蠢的错误。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-21
  • 2021-07-12
  • 2015-12-23
  • 1970-01-01
相关资源
最近更新 更多