# Maths - Decomposition of rotations - Forum discussion.

 By: nobody ( Nobody/Anonymous ) Rotation decomposition direction + twist by q   2004-02-19 07:20 Just found fun thing, when developed some rotational constraints. I need to decompose rotation by shortest arc component, and did it like shoemake do in it's "Fiber Bundle Twist Reduction" Ken Shoemake in "Graphics Gems IV". did the shortest arc from direction to full rotated direction. /** Decompose rotation by rotation of direction vector and twist, around direction vector composite = without_twist * twist == orientation */ void dir_twist_decomposition( const xxquaternion& orientation, const vector3& default_dir, xxquaternion& dir_rotation, xxquaternion& twist_rotation ) { vector3 rotated_dir( orientation.rotate( default_dir ) ); dir_rotation.shortest_arc( default_dir, rotated_dir ); twist_rotation = dir_rotation.inverted() * orientation; #ifdef _DEBUG xxquaternion composite = dir_rotation * twist_rotation; composite -= orientation; ASSERT( composite.magnitude() < 0.00001f ); #endif //_DEBUG } But i fund the MORE faster way to do it : void dir_twist_decomposition_2( const xxquaternion& orientation, const vector3& default_dir, xxquaternion& dir_rotation, xxquaternion& twist_rotation ) { vector3 rotation_axis( orientation.x, orientation.y, orientation.z ); // return projection v1 on to v2 (parallel component) // here can be optimized if default_dir is unit vector3 proj = projection( rotation_axis, default_dir ); twist_rotation.set( proj.x, proj.y, proj.z, orientation.w ); twist_rotation.normalize(); dir_rotation = orientation * twist_rotation.inverted(); #ifdef _DEBUG xxquaternion composite = dir_rotation * twist_rotation; composite -= orientation; ASSERT( composite.magnitude() < 0.00001f ); #endif //_DEBUG } Do it have a math proof ? So i can make a constraint to the Direction component and than compose again with twist component.
 By: martinbaker ( Martin Baker ) RE: Rotation decomposition direction + twist by q   2004-02-20 08:42 Thank you very much for this, this is very interesting, as you say, for applying constraints to jointed systems. I have started a page at: https://www.euclideanspace.com/maths/geometry/rotations/for/decomposition/ Although, so far I don't have much information, I'll have to think about it. Martin
 By: nobody ( Nobody/Anonymous ) RE: Rotation decomposition direction + twist by q   2004-02-23 00:41 Hi Martin. It is Minorlogic. I forgot to use my registration, cookies didn't work . It was my previous post . i started to work a little with sceletal animations and inverse kinematics (joints). And may be will find some thing another intresting. Your illustration is right about thing that i posted. It was used for me to constraint direction vector without change in twist.
 By: minorlogic ( Michaele Norel ) RE: Rotation decomposition direction + twist by q   2004-02-23 03:17 It is often called (as i found) "Swing" - "Twist" decomposition
 By: martinbaker ( Martin Baker ) RE: Rotation decomposition direction + twist by q   2004-02-23 08:57 Hi Minorlogic, Its good to hear from you again and an interesting topic (as your messages always are). I would like to implement kinematics in the program on my website and I would also like to find a mathematical way to define constraints for different types of join listed here: https://www.euclideanspace.com/physics/kinematics/joints/jointstructures/ So if you discover any more I would be very interested to hear about it. Thanks, Martin
 By: nobody ( Nobody/Anonymous ) RE: Rotation decomposition direction + twist by q   2004-02-24 00:45 Thanks For nice response. https://www.euclideanspace.com/physics/kinematics/joints/jointstructures/ Very good page. Can you tell me where come from the joint terms ? Name Symbol DOF Revolute joints R 1 Prismatic joints P 1 Helical joints - 1 Cylindrical joints RP 2 Spherical joints 3R 3 Planar joints Have you seen the ODE page ? http://opende.sourceforge.net/ode-latest-userguide.html with it's own terms 7.3.1. Ball and socket 7.3.2. Hinge 7.3.3. Slider 7.3.4. Universal 7.3.5. Hinge-2 7.3.6. Fixed 7.3.7. Contact 7.3.8. Angular Motor
 By: martinbaker ( Martin Baker ) RE: Rotation decomposition direction + twist by q   2004-02-24 08:22 Minorlogic I think I got it from the character animation FAQ: http://www.morrowland.com/apron/article/general/character%20animation/index.php But there also seem to be other definitions, this one has very good graphics and suggests that there the types can be reduced to 3. http://www.robotics.utexas.edu/rrg/learn_more/low_ed/joints/#types Your right, I should look at ODE, no point in reinventing the wheel, or in this case the robot arm! Martin
 By: minorlogic ( Michaele Norel ) RE: Rotation decomposition direction + twist by q   2004-02-25 00:46 Hi Martin. Seems that my method don't work correct. here is a disscusion on topic end http://www.flipcode.com/cgi-bin/msg.cgi?showThread=00009150&forum=3dtheory&id=-1 and Christian Sch?ler shows disproof. I need the time to be sure in this.
 By: minorlogic ( Michaele Norel ) RE: Rotation decomposition direction + twist by q   2004-03-04 00:27 The first try of the proof. input quaternion rotation(a, w) vector3 d ->direction of decomposition vector3 a -> axis of rotation of quaternion vector3 p ->paralel component , the projection of "a" on "d" vector3 o ->orthogonal component , o = a - p quaternion twist( p, w ); by the multiplication rules recover the swing from twist q*q' = q( cross(v,v') + wv' + w'v, ww' - dot(v,v') ) swing = rotation * twist.conjugated() = = rotation(a, w) * twist_conjugated( -p, w ) = = swing( cross(a,-p) - p*w + a*w, w*w - dot(a, -p) )= = swing( cross(a,-p) + w*( a - p), w*w - dot(a, -p) )= = swing( cross(a,-p) + w*o, w*w - dot(a, -p) ); Here look at the end, the vector part of given swing cross( a, -p ) + w*o , the cross( a, -p ) and w*o both lay in the plane that perpendicular to the direction of decomposition, and it's sum lay in that plane too. What we have ? the swing and twist, when multiplied give the "rotation". The twist rotate only by "direction axis", and swing rotation axis is perpendicular to the twist rotation axis. So we proofe that such a decomposition is valid.
 By: martinbaker ( Martin Baker ) RE: Rotation decomposition direction + twist by q   2004-03-04 07:51 Minorlogic, Can you explain the terms a bit more, I have added some definitions to the web page: https://www.euclideanspace.com/maths/geometry/rotations/for/decomposition/ but I'm not quite sure how to map these definitions to the input of your proof? Martin
 By: minorlogic ( Michaele Norel ) RE: Rotation decomposition direction + twist by q   2004-03-05 01:33 /** Decompose the rotation on to 2 parts. 1. Twist - rotation around the "direction" axis 2. Swing - rotation around axis that is perpendicular to "direction" axis The rotation can be composed back by composite_rotation = swing * twist ( == orientation ) have singularity in case of swing_rotation close to 180 degrees rotation. input quaternion can be nonunit length output is unit quats if input unit */ void swing_twist_decomposition( const xxquaternion& rotation, const vector3& direction, xxquaternion& swing, xxquaternion& twist) { vector3 rotation_axis( rotation.x, rotation.y, rotation.z ); // return projection v1 on to v2 (parallel component) // here can be optimized if direction is unit vector3 proj = projection( rotation_axis, direction ); twist.set( proj.x, proj.y, proj.z, rotation.w ); twist.normalize(); swing = rotation * twist.conjugated(); } In your terms all this right. Rotation -> is a full quaternion rotation direction -> is a "direction vector" But the full rotation rotation == swing*twist and rotation != twist*swing The rotation compositions is not commutative. //------------------------------------ from your page : D = original vector direction N = new vector direction A = axis of swing rotation R = axis of combined rotation Let Us take by Twist quaternion the quaternion of look Twist ( TR, W ) where TR = axis of twist rotation W = combined rotation scalar part of quaternion TR = axis of twist rotation computed like Projection of R = axis of combined rotation to the D = original vector direction TR = projection(R, D ); If the combined_rotation = swing*twist than swing = combined_rotation/twist = swing = combined_rotation*twist.inversed() ; ( or conjugated if the twist is unit quat) swing = combined_rotation*twist.inversed() ; combined_rotation have two parts vector part -> R and scalar part W combined_rotation( R, W) twist represented as twist(TR, W) and twist conjugatad as twist( -TR, W) than swing rotation can be calculated by quaternion multiplication rule q*q' = q( cross(v,v') + wv' + w'v, ww' - dot(v,v') ) as combined_rotation( R, W) * twist( -TR, W) = swing( cross(R, -TR) + R*W - TR * W, W*W - dot(R, -TR) ) = swing( cross(R, -TR) + W*(R - TR), W*W - dot(R, -TR) ) The vector cross(R, -TR) perpendicular to the D because -TR lay on the "D", and W*(R - TR) perpendicular because: W*( R - TR ) -> is a W*( R - projection (R, D )) -> is a W*( perpendicular_component(R, D )) ; The sum of two perpendicular to D vectors give the vector that is perprndicular to D too, because thay lay in one plane , and tham composition lay in that plane. because of swing was computed as swing = combined_rotation*twist.inversed() ; their composition combined_rotation = swing*twist; And we know their properties that Twist rotate only about D vector and Swing only about vector that is parallel to D. It all work in the Pure rotation , when D represent the direction in LOCAL object orientation frame. So if we have the Rotation R1 and R2 , and want to find Swing and Twist from R1 to R2 about any Direction vector. We need to made such : find the delta rotation such that R2 = R1 * Delta_Rotation Delta_Rotation = R2/R1 Than decompose the Delta_Rotation by Direction Vector in the Delta_Rotation Frame. More info can be found in Shoemake "Fiber bundle twist reduction" or in it's tutorial. There he finf the Swing rotation first , by finding "shortest arc" between Direction Vector and New Direction Vector And than find the Twist.

 metadata block see also: Correspondence about this page Book Shop - Further reading. Where I can, I have put links to Amazon for books that are relevant to the subject, click on the appropriate country flag to get more details of the book or to buy it from them.       Graphics Gems - Lots of useful algorithms and snippets of theory - These are reference books rather than books you read from cover to cover. If you can afford it they are worth having on the shelf (I wish I could!) They might just solve a problem which could otherwise take days to work out. Other Math Books

This site may have errors. Don't use for critical systems.