User:LindaB Helendale/rot2roll pitch yaw

From Second Life Wiki
Jump to navigation Jump to search

Roll, pitch and yaw are commonly used object related rotations (intrinsic Tait-Bryan angles) in avionics, sailing and navigation. Here are conversion functions between LSL rotation and roll, pitch and yaw angles.

Note that in http://wiki.secondlife.com/wiki/LlRot2Euler llRot2Euler it is (somewhat) imprecisely stated that it returns roll, pitch and yaw angles. However, LSL Euler angles are extrinsic Tait-Bryan angles, in Z Y X order. With extrinsic rotations, after the Z-rotation (yaw) the Y-rotation is done in the world coordinates, rotating the rotated vertices around the world Y-axis, and similarly with X. As the Y-rotation is not with respect to the local Y-axis it does not represent the pitch angle. For a 90 degree yaw, the Y-rotation will actually cause roll around the local X-axis that is aligned with the world Y-axis. If the order of Euler angles in LSL were X Y Z the angles would be proper nautical angles (and llRot2Euler would return the same values as rot2roll_pitch_yaw below), but the order is built-in in the llRot2Euler and llEuler2Rot functions.


 
vector rot2roll_pitch_yaw(rotation R)
{
    /*
    Convert rotation to roll, pitch and yaw angles 
    (c) LindaB Helendale
    Permission to use this code in any way granted
    
    Input: rotation (quaternion) R
    Output: vector <roll,pitch,yaw> 
    
    Roll, pitch and yaw are body-related rotations (intrinsic Tait-Bryan angles): 
    first yaw to the heading, then pitch around the local Y-axis and then roll 
    around the local X-axis (nose direction). This is equivalent to world coordinate 
    rotations (extrinsic Tait-Bryan angles, or LSL Euler angles) in order roll, pitch and yaw. 
    Thus the rotation R is recovered from the roll, pitch and yaw angles by inverting 
    the order of the rotations (since in LSL they are in Z Y X or yaw, pitch, roll order):
        rotation R = llEuler2Rot(<roll,0,0>) * llEuler2Rot(<0,pitch,0>) * llEuler2Rot(<0,0,yaw>);
        
    Reference: http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
    */
    vector eulerXYZ = < llAtan2(2*(R.s*R.x+R.y*R.z),1-2*(R.x*R.x+R.y*R.y)), 
                        llAsin(2*(R.s*R.y-R.z*R.x)), 
                        llAtan2(2*(R.s*R.z+R.x*R.y), 1-2*(R.y*R.y+R.z*R.z)) >;
    return(eulerXYZ);
}

rotation roll_pitch_yaw2rot(vector R)
{
    // convert vector <roll,pitch,yaw> to LSL rotation
    return llEuler2Rot(<R.x,0,0>) * llEuler2Rot(<0,R.y,0>) * llEuler2Rot(<0,0,R.z>);
}