Maths - Decomposition of rotations - Forum discussion.

By: nobody ( Nobody/Anonymous )
file 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 )
file 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 )
file 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 )
file 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 )
file 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 )
file 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 )
file 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 )
file 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 )
file 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 )
file 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 )
file 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.

 

cover 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.

cover Graphics Gems II

cover Graphic Gems III: IBM Version (with diskette)

cover Graphics Gems IV: IBM Version (with Diskette)

cover Graphics Gems V: IBM Version (with disk)

Other Math Books

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

Copyright (c) 1998-2023 Martin John Baker - All rights reserved - privacy policy.