如何旋转由四元数表示的对象集?

时间:2012-02-15 02:38:21

标签: 3d rotation quaternions

假设对象的方向由四元数表示。 如果我想旋转该对象,我只需将四元数与旋转四元数相乘。

object.q = q_rotation*(object.q)

然后是由一组较小的对象组成的对象。如何旋转它?

class Object
{
 public:
    std::vector<Object> part;
    Point centre; //Point is basically double x, y, z
    Quaternion q;

    void RotateBy(Quaternion q_rotation);

};

说这个对象有两个部分。每个部分都有自己的中心和q,它们相对于整个空间(不是相对于主要对象的中心)。

然后现在我想旋转对象,它的所有部分也应该旋转并更新到新的中心和q。零件将相对于主要物体的中心旋转。

我该怎么办?我发现了许多链接,显示如何使用转换矩阵来完成此操作。但有没有办法直接使用四元数?

或许,换句话说,如何在原点移动的情况下旋转四元数?

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

它实际上比我想象的要容易。我想那些线性代数类实际上很有用。

在这种情况下,我假设您将某些3D几何体定义为名为“GeomType”的类。 “对象”由许多“GeomType”组成。这里的'对象'很简单,是'GeomType'的向量。 “对象”中的每个“GeomType”由相对于“对象”的中心点的中心点位置和表示从默认中性位置的旋转的四元数定义。这是一些示例代码。

还有PointType,它基本上是(x,y,z)的double,而QuaternionType也是(w,x,y,z),也是double。

//suppose you have this Object
std::vector <GeomType> Object; //and it is already initialized
//you were given the rotation quaternion and the point to rotate about.
PointType origin;
QuaternionType Q2;

//rotate the GeomTypes
unsigned int numGeom = Object.size();
for (unsigned int i = 0; i <numGeom; i++)
{
    //1. translate the individual GeomType
    const PointType geomCentre= Object[i].GetCentrePosition();

    //Rotate vector representing the direction and distance from origin to geom
    //note that the origin of rotation does not need to be the centre
    const PointType newPos = 
          RotateAbout(PointType(geomCentre[0], geomCentre[1], dGeomPos[2]),
                                                         Q2, origin);
    //move the GeomType to the new position
    Object[i].SetCentrePosition(newPos.GetX(), newPos.GetY(), newPos.GetZ());

    //2. Rotate the GeomType
    QuaternionType Qo = Object[i].GetQuaternion(); //current quaternion of the geom
    QuaternionType Qr; //resultant quaternion of the geom

    Qr = Q2*Qo; //rotating by multiplication 
    //(please check other sites on how to multiply quaternions)

    Object[i].SetQuaternion(Qr); //set the new quaternion
}

这是RotateAbout函数,用于围绕点旋转矢量

PointType RotateAbout(const PointType &InitPos, const QuaternionType &Qr, const PointType& Origin)
{
     //the vector from the origin
     PointType newVec = InitPos-Origin;
     //extract the magnitude
     const double vecLength = newVec.Length();

     //normalize the vector and rotate that vector
     //then translate the geom to the new position
     newVec = Origin + Qr*(newVec.GetUnitVector())*vecLength;

     return newVec;
}

以下是相对于某个点旋转一组3D对象的常规程序。它应该适用于任何编程语言,尽管它是基于C ++编写的。