Search code examples
3drotationquaternions

How to rotate set of objects represented by quaternion?


Say a object's orientation is represented by a quaternion. If I want to rotate that object, I simply multiply the quaternion with the rotational quaternion.

object.q = q_rotation*(object.q)

Then for an object that is composed of made up of a set of smaller objects. How do I rotate it?

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

    void RotateBy(Quaternion q_rotation);

};

Just say this object has two part's. And each part could have its own centre and q, and they relative to the entire space (not relative to the centre of the main object).

Then now I want to rotate the object, and all its parts should rotate as well and get updated to their new centres and q's. The parts will be rotated relative to the main object's centre.

How should I do that??? I have found many some link that show how to do this with transformational matrice. But is there a way to do it directly with the quaternion?

Perhaps, in other word, how to rotate a quaternion with the origin shifted?

Thank you for your help!


Solution

  • It is actually easier than I thought. I guess those linear algebra classes was actually useful.

    In this case, I assume you have some 3D geometry defined as a class named 'GeomType'. An 'Object' is made up of many 'GeomType'. Here an 'Object' is simple a vector of 'GeomType'. Each 'GeomType' in an 'Object' is defined by it centre point location relative to the centre point of the 'Object' and an quaternion which represent the rotation from a default neutral position. Here is some sample code.

    There are also PointType which is basically (x, y, z) in double, and QuaternionType which is (w,x,y,z) in double as well.

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

    This is the RotateAbout function which was used to rotate a vector about a point

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

    Here is the general program to rotate a set of 3D objects relative to a point. It should be applicable to any programming language though it is written based on C++.