Camera Orbiting a Point with Quaternions

So I currently use quaternions to store and modify the orientation of the objects in my OpenGL scene, as well as the orientation of the camera. When rotating these objects directly (ie saying I want to rotate the camera Z amount around the Z-axis, or I want to rotate an object X around the X-axis and then translate it T along its local Z-axis), I have no problems, so I can only assume my fundamental rotation code is correct.

However, I am now trying to implement a function to make my camera orbit an arbitrary point in space, and am having quite a hard time of it. Here is what I have come up with so far, which doesn't work (this takes place within the Camera class).

    //Get the inverse of the orientation, which should represent the orientation 
    //"from" the focal point to the camera
    Quaternion InverseOrient = m_Orientation;
    InverseOrient.Invert();

    ///Rotation
    //Create change quaternions for each axis
    Quaternion xOffset = Quaternion();
    xOffset.FromAxisAngle(xChange * m_TurnSpeed, 1.0, 0.0, 0.0);

    Quaternion yOffset = Quaternion();
    yOffset.FromAxisAngle(yChange * m_TurnSpeed, 0.0, 1.0, 0.0);

    Quaternion zOffset = Quaternion();
    zOffset.FromAxisAngle(zChange * m_TurnSpeed, 0.0, 0.0, 1.0);

    //Multiply the change quats into the inversed orientation quat
    InverseOrient = yOffset * zOffset * xOffset * InverseOrient;

    //Translate according to the focal distance
    //Start with a vector relative to the position being looked at
    sf::Vector3<float> RelativePos(0, 0, -m_FocalDistance);
    //Rotate according to the quaternion
    RelativePos = InverseOrient.MultVect(RelativePos);

    //Add that relative position to the focal point
    m_Position.x = m_FocalPoint->x + RelativePos.x;
    m_Position.y = m_FocalPoint->y + RelativePos.y;
    m_Position.z = m_FocalPoint->z + RelativePos.z;

    //Now set the orientation to the inverse of the quaternion 
    //used to position the camera
    m_Orientation = InverseOrient;
    m_Orientation.Invert();

What ends up happening is that the camera rotates around some other point - certainly not the object, but apparently not itself either, as though it were looping through space in a spiral path.

So this is clearly not the way to go about orbiting a camera around a point, but what is?


I would operate on the camera first in spherical coordinates and convert to quaternions as necessary.

Given the following assumptions:

  • The camera has no roll
  • The point you are looking at is [x, y, z]
  • You have yaw, pitch angles
  • [0, 1, 0] is "up"
  • Here is how to calculate some important values:

  • The view vector: v = [vx, vy, vz] = [cos(yaw)*cos(pitch), sin(pitch), -sin(yaw)*cos(pitch)]
  • The camera location: p = [x, y, z] - r*v
  • The right vector: cross product v with [0, 1, 0]
  • The up vector: cross product v with the right vector
  • Your view quaternion is [0, vx, vy, vz] (that's the view vector with a 0 w-component)
  • Now in your simulation you can operate on pitch/yaw, which are pretty intuitive. If you want to do interpolation, convert the before and after pitch+yaws into quaternions and do quaternion spherical linear interpolation.

    链接地址: http://www.djcxy.com/p/81760.html

    上一篇: OpenGL,GLM四元数旋转

    下一篇: 相机与四元数的轨道点