Combine Rotation Axis Vectors

I'm experimenting with using axis-angle vectors for rotations in my hobby game engine. This is a 3-component vector along the axis of rotation with a length of the rotation in radians. I like them because:

  • Unlike quats or rotation matrices, I can actually see the numbers and visualize the rotation in my mind
  • They're a little less memory than quaternions or matrices.
  • I can represent values outside the range of -Pi to Pi (This is important if I store an angular velocity)
  • However, I have a tight loop that updates the rotation of all of my objects (tens of thousands) based on their angular velocity. Currently, the only way I know to combine two rotation axis vectors is to convert them to quaternions, multiply them, and then convert the result back to an axis/angle. Through profiling, I've identified this as a bottleneck. Does anyone know a more straightforward approach?


    You representation is equivalent to quaternion rotation, provided your rotation vectors are unit length. If you don't want to use some canned quaternion data structure you should simply ensure your rotation vectors are of unit length, and then work out the equivalent quaternion multiplications / reciprocal computation to determine the aggregate rotation. You might be able to reduce the number of multiplications or additions.

    If your angle is the only thing that is changing (ie the axis of rotation is constant), then you can simply use a linear scaling of the angle, and, if you'd like, mod it to be in the range [0, 2π). So, if you have a rotation rate of α raidans per second, starting from an initial angle of θ0 at time t0, then the final rotation angle at time t is given by:

    θ(t) = θ0+α(t-t0) mod 2π

    You then just apply that rotation to your collection of vectors.

    If none of this improves your performance, you should consider using a canned quaternion library as such things are already optimized for the kinds of application you're disucssing.


    You can keep them as angle axis values.

    Build a cross-product (anti-symmetric) matrix using the angle axis values (x,y,z) and weight the elements of this matrix by multiplying them by the angle value. Now sum up all of these cross-product matrices (one for each angle axis value) and find the final rotation matrix by using the matrix exponential.

    If matrix A represents this cross-product matrix (built from Angle Axis value) then,

    exp(A) is equivalent to the rotation matrix R (ie, equivalent to your quaternion in matrix form) .

    Therefore,

    exp (A1 + A2) = R1 * R2
    

    probably a more expensive calucation in the end...


    You should use unit quaternions rather than scaled vectors to represent your rotations. It can be shown (not by me) that any representation of rotations using three parameters will run into problems (ie is singular) at some point. In your case it occurs where your vector has a length of 0 (ie the identity) and at lengths of 2pi, 4pi, etc. In these cases the representation becomes singular. Unit quaternions and rotation matrices do not have this problem.

    From your description, it sounds like you are updating your rotation state as a result of numerical integration. In this case you can update your rotation state by converting your rotational rate (omega) to a quaternion rate (q_dot). If we represent your quaternion as q = [q0 q1 q2 q3] where q0 is the scalar part then:

    q_dot = E*omega
    

    where

        [ -q1 -q2 -q3 ]
    E = [  q0 -q3  q2 ]
        [  q3  q0 -q1 ]
        [ -q2  q1  q0 ]
    

    Then your update becomes

    q(k+1) = q(k) + q_dot*dt

    for simple integration. You could choose a different integrator if you choose.

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

    上一篇: 为什么四元数用于旋转?

    下一篇: 结合旋转轴矢量