Sign in to follow this  

Quaternion\Coord system

This topic is 4333 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, Let be a quaternion Q1 and a vector U1 that represent a coordinate system (unit quaternion + vector = matrix = coordinate system). Let be a quaternion Q2 and a vector U2. How can I calculate the quaternion Q2' the Q2 quaternion in the ( Q1, U1 ) coordinate system ? Q2' = Q1*Q2*1/Q1 ? Q2' = Q1*Q2*Q1_ (Q1_ conjugate of Q1) ? And what about the vector U2' ? U2' = Q1.matrix*U2 + U1 ? U2' = Q1*U*Q1_ + U1 ? That I want exactly is the rotation quaternion in a coordinate system given by Q1 and U. Can you please help me on this subject ? Thank You.

Share this post


Link to post
Share on other sites
hmm, this is very interesting... You mean, the unit quaternion Q1 implies an orientation (version of the system's axes) plus the vector U1 to translate the origin to a new point... This sounds like a typical linear trasformation but expressed as a pair of a quaternion and a vector... Intriguing!

I believe that U1 shouldn't affect the transformation of any quaternion -or vector- to the new system of coordinates. For vectors, this is obvious since vectors are not affected by translation, if they are moved so to remain parallel to their original orientation. (unless of course, you want to treat vectors as points rather as abstact directions of given magnitude)
Also, any quaternion is merely the quotient of two vectors, therefore it should remain unaffected by U1 too, when projected to the new system.

I will have to give this a little more thought though, before I can suggest any formula

Share this post


Link to post
Share on other sites
This sort of thing can be a bit easier with 4x4 matrices, but try this:
Q2' = Q1.Conjugate()*Q2
U2' = Q1.Conjugate().Rotate(U2-U1)
Where the Rotate() function applies the quaternion rotation formula q*p*conjugate(q). Anyway, not positive I got the order right, but that's the general idea.

Share this post


Link to post
Share on other sites
Quote:
Original post by someusername
hmm, this is very interesting... You mean, the unit quaternion Q1 implies an orientation (version of the system's axes) plus the vector U1 to translate the origin to a new point... This sounds like a typical linear trasformation but expressed as a pair of a quaternion and a vector... Intriguing!


:D

Quote:
Original post by someusername
I believe that U1 shouldn't affect the transformation of any quaternion -or vector- to the new system of coordinates. For vectors, this is obvious since vectors are not affected by translation, if they are moved so to remain parallel to their original orientation. (unless of course, you want to treat vectors as points rather as abstact directions of given magnitude)
Also, any quaternion is merely the quotient of two vectors, therefore it should remain unaffected by U1 too, when projected to the new system.

I will have to give this a little more thought though, before I can suggest any formula


Oh, U represents a point yes, the coordinate system center.

Share this post


Link to post
Share on other sites
Quote:
Original post by jyk
This sort of thing can be a bit easier with 4x4 matrices, but try this:
Q2' = Q1.Conjugate()*Q2
U2' = Q1.Conjugate().Rotate(U2-U1)
Where the Rotate() function applies the quaternion rotation formula q*p*conjugate(q). Anyway, not positive I got the order right, but that's the general idea.


Q1.Conjugate().Rotate(U2) + U1 I think for what I want. Q2 and U2 represent a transformation I want in the coordinate system (U1, Q1).

Share this post


Link to post
Share on other sites
The quaternion could be converted to a rotation matrix, itself interpretable as a basis. The vector could be interpreted as a point and used as the origin. So a frame
F(Q,U)
could be defined from the both.

If done so, you have two frames
F1 := F(Q1,U1) and F2 := F(Q2,U2)
both given in the global frame, I assume.

To transform from global to local frame the inverse transform has to be applied. In matrix (column order) form, that would be like
( T1 * R1 )-1 = R1-1 * T1-1

Re-interpreting it with quaternions, it means that
Q2' := Q1-1 * Q2
(since orientations are invariant to translations), and
U2' := Q1-1 * ( U2 - U1 ) * Q1
where -U1 expresses the negative T1, and the product of quaternion and vector expresses the quaternion rotation applied to a vector.


EDIT: Hmm, from the matrix order I would assume the form of jyk is right, since T1-1 is to be applied before R1-1 (see my interpretation above). But I'm not sure at all.

[EDIT: There was a U2 vs U1 exchange.]
[EDIT: And moreover a *Q1 was missed.]


[Edited by - haegarr on January 30, 2006 8:54:00 AM]

Share this post


Link to post
Share on other sites
Thank you for this formula, I haven't it at all.

But a thing is not clear in my explanation.

F = (Q2, U2) represent a transformation. I need the transformation F', a global space transformation, that is the transformation F in the coordinate system (Q1, U1).

(here U1 is a point, U2 a vector.. sorry that was not clear)

With matrix, i use generaly : R2' = R1*R2*R1^(-1) where R1 is the coordinate system matrix, R2 the rotation matrix wich is expressed in the global space but in fact is a R1 space rotation and R2' the result (the rotation matrix R2 of the R1 space expressed in the global space).

Is that clear ? :D

Share this post


Link to post
Share on other sites
Quote:
Original post by Woodchuck
Thank you for this formula, I haven't it at all.

But a thing is not clear in my explanation.

F = (Q2, U2) represent a transformation. I need the transformation F', a global space transformation, that is the transformation F in the coordinate system (Q1, U1).
If you mean you want F(Q2,U2) as expressed in the local space of F(Q1,U1), where both F()'s are given in world space, then that's the equation that haegarr and I were trying to give (I think)...
Quote:
(here U1 is a point, U2 a vector.. sorry that was not clear)
Now I'm confused - maybe we're talking about different things. Why is U1 a point and U2 a vector?
Quote:
With matrix, i use generaly : R2' = R1*R2*R1^(-1) where R1 is the coordinate system matrix, R2 the rotation matrix wich is expressed in the global space but in fact is a R1 space rotation and R2' the result (the rotation matrix R2 of the R1 space expressed in the global space).

Is that clear ? :D
Hehe, 'fraid not :) Are those 4x4 matrices, or 3x3? When you say 'coordinate system matrix', do you mean a full affine transform? If so, perhaps some different variable names would help.

Better yet, maybe you could describe the context, or what it is you're trying to do. That might clear things up.

Share this post


Link to post
Share on other sites
So (Q2,U2) is a local transformation given in the frame (Q1,U1), and you want the transformation being transformed into the parent frame of (Q1,U1)? So you mean a "simple" transformation concatenation?

In hom. matrix (column vector) form I expect this being
T1 * R1 * T2 * R2 * X
or in affine matrix form
T1 + R1 * ( T2 + R2 * X ) == T1 + R1 * T2 + R1 * R2 * X
where X is a variable vector to allow the following step.

Comparing the coefficients with the normal form yields in
T' := T1 + R1 * T2
R' := R1 * R2
doesn't it?

Confusion everywhere ;)

EDIT:
Quote:
Original post by jyk
Now I'm confused - maybe we're talking about different things. Why is U1 a point and U2 a vector?

I assume it is because U1 denotes the origin of a co-ordinate frame, and U2 denotes a translation vector. Similarly, Q1 denotes an orientation, and Q2 denotes a rotation. Say, (Q1,U1) is a frame and (Q2,U2) a transformation. Just a question of convention...

Share this post


Link to post
Share on other sites
I think the quaternion for the base is Q2*Q1T, since the axes of (Q1,U1) must be first mapped to the world axes and then onto those implied by Q2.

Any vector U in (Q1,U1) space must be mapped to:
U' = Q2*Q1T*(U-U1) + U2

I can't guarantee this being correct, though. Let me know if you try it anyway.

edit:
use U' = Q2*Q1T*U + (U2-U1) instead. It doesn't make sense subtracting vectors expressed in different frames of reference

[Edited by - someusername on January 29, 2006 9:38:16 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by haegarr
So (Q2,U2) is a local transformation given in the frame (Q1,U1), and you want the transformation being transformed into the parent frame of (Q1,U1)? So you mean a "simple" transformation concatenation?


That's it. I think.. =)


Quote:
Original post by haegarr
I assume it is because U1 denotes the origin of a co-ordinate frame, and U2 denotes a translation vector. Similarly, Q1 denotes an orientation, and Q2 denotes a rotation. Say, (Q1,U1) is a frame and (Q2,U2) a transformation. Just a question of convention...


That's it! =)

Ok, so this is just concatenation. I damn don't now why I have this formula in head : R2*R1*1/R2 for matrix33.


Quote:
Original post by jyk
Where the Rotate() function applies the quaternion rotation formula q*p*conjugate(q)


Ok so, what should i do with all of that.

Q2' := Q1.Conjugate*Q2*Q1 ?
U2' := U1 + Q1.Conjugate*Quat(U2)*Q1 ?

Sorry, i'm a little lost. What is the formula for rotation concatenation in term of quaternion ? What exactly do 'Rotate()' ?

[ --- English lesson --- ]
You say frame... mmh should i use this world instead of coordinate system ? Parent frame, frame... Sounds good ^^
[ --- English lesson --- ]

Share this post


Link to post
Share on other sites
Quote:
Original post by Woodchuck
Q2' := Q1.Conjugate*Q2*Q1 ?
U2' := U1 + Q1.Conjugate*Quat(U2)*Q1 ?

IMHO (say if I'm on the right trip) suggest
Q2' := Q1 * Q2
to concatenate both rotations (as I recall correct this order means that Q2 is more local, what exactly is needed here), and
U2' := U1 + Q1 * [U2,0] * conj(Q1)

Quote:
Original post by Woodchuck
What is the formula for rotation concatenation in term of quaternion ? What exactly do 'Rotate()' ?

As far as I know the product of 2 (unit) quaternions is the concatenation of the represented rotations. However, you have to consider that the product isn't commutative, so that the order counts.

The Rotate() function mentioned by jyk is for rotating a vector [X,0] (notice the extension w/ zero) by a quaternion w/o the need to convert the quaternion to a matrix first:
Rotate(X;Q) := Q * [X,0] * conj(Q)

See e.g. the Matrix and Quaternion FAQ:
http://www.j3d.org/matrix_faq/matrfaq_latest.html

Quote:
Original post by Woodchuck
[ --- English lesson --- ]
You say frame... mmh should i use this world instead of coordinate system ? Parent frame, frame... Sounds good ^^
[ --- English lesson --- ]

Well, I use the term frame since I've read the article "A Coordinate Free Geometry ADT". My natural language isn't english, so I can't guarantee its correctness. However, until now nowbody here in the forum has complained about it, although I've used the term nearly a thousand times ;)


I hope this helps (and even more it is correct; I'm not sure about the multiplication order).

Share this post


Link to post
Share on other sites
Quote:
Original post by Woodchuck
EDIT: A more clean link about matrix and quaternion faq http://www.flipcode.com/documents/matrfaq.html#Q47

Please notice that your link refers to
FAQ Version 1.4 26th December 1998
but my link to
FAQ Version 1.21 30th November 2003
(but I don't claim that this is the newest version).

Share this post


Link to post
Share on other sites
Quote:
Original post by haegarr
Quote:
Original post by Woodchuck
EDIT: A more clean link about matrix and quaternion faq http://www.flipcode.com/documents/matrfaq.html#Q47

Please notice that your link refers to
FAQ Version 1.4 26th December 1998
but my link to
FAQ Version 1.21 30th November 2003
(but I don't claim that this is the newest version).


Oh yes, that's right.

Share this post


Link to post
Share on other sites
I'm sorry if this should be obvious by now, but which of the following holds afterall?

1) Is (Q1,U1) a transformation that maps the usual world axes vectors ({1,0,0}, {0,1,0}, {0,0,1}) to the world co-ordinate vectors (x1, y1, z1), and what you are looking for, is a transformation (Q,U) expressed in (Q2,U2) that maps the base vectors of (Q2, U2) to the world coordinate vectors (x1, y1, z1) ?

OR

2) (Q2, U2) is transformation expressed in (Q1,U1) coordinates and you want its equivalent in the world frame of reference?

Just out of curiosity, can you post the correct equations, if you try what the above posters suggested?

Share this post


Link to post
Share on other sites
Somewhat offtopic but possibly useful info on quats:

I wrote the 'coordinate system' class that is mostly equivalent in usage to 4x4 matrix (can be multiplied, etc) but has quaternion and vector inside (quaternion for rotation, vector for translation). It's very convenient for doing things like that.

Explanations of how you can figure out what to do with quaternions:

The basic idea of this is very simple, mostly same as with 3x3 matrix for rotation and vector for translation.
Let's first define
Q rotate V = Q*V*~Q , in other words, rotation of vector by quaternion. In programming it can be written as Q.rotate(V)
This "rotate" is much like rotation_matrix*vector, in that it also does rotation, and all properties of rotation apply.
For instance,
1.) Q rotate (V1+V2) = (Q rotate V1) + (Q rotate V2)
2.) Q1 rotate (Q2 rotate V) = (Q1*Q2) rotate V
3.) (~Q) rotate (Q rotate V) = V
The "rotate" is really sorta multiplication & from now on i will assume it have same precedence. These formulas can all be derived from definition of "rotate"

Now, we can define Euclidean transform(?) i.e. rotation and translation, as
E=(Q, P)
where P is translation and Q is quaternion. We can make it behave just like 4x4 matrix. We can define E*V to mean rotation&translation of V by E just as if E would be an 4x4 matrix, define ~E as inverse transform, and define E1*E2 as concatenated rotations.

So we have:
V' = E*V = (Q rotate V) + P , where Q is rotation and P is translation.
The inverse transform can be easily found as
V' = (Q rotate V) + P
V' - P = Q rotate V
~Q rotate (V' - P) = V
~Q rotate V' - ~Q rotate P = V

That is, for
E=(Q,P)
inverse is
~E=(~Q, - (~Q rotate P))

Another thing we can be interested in is concatenation of transformations. Say V is transformed by E1 then by E2 .
(E2*E1)*V = P2+Q2 rotate (P1+Q1 rotate V) = P2 + Q2 rotate P1 + Q2*Q1 rotate V
So we have
E2*E1=(Q2*Q1,P2 + Q2 rotate P1)


There is the code i use (somewhat crude), may be more readable than math above:

// ignore the templates - them is there just so i can use it with
// floats and doubles alike.
// You can just assume T is double and "something<t>"
// is "somethingd" to indicate that it's using double.

template <class T>
struct CoordSys
{
Quaternion<T> orientation;
Vec3<T> position;
CoordSys()
{}
;
CoordSys(Quaternion<T> o,Vec3<T>pos)
{
position=pos;
orientation=o;
};
//helpser
void Translate(const Vec3<T> &by)
{
position+=QuaternionToMatrix(orientation)*by;
};
void Rotate(const Quaternion<T> &by)
{
orientation=
#ifndef dont_normalize
Normalized
#endif
(orientation*by);
};
inline void Rotate(const Vec3<T> &axis,T angle)
{
orientation=
#ifndef dont_normalize
Normalized
#endif
(orientation*(Quaternion<T>(axis,angle)));
}
};

template<class T>
CoordSys<T> operator*(const CoordSys<T> &c1,const CoordSys<T> &c2)
{
CoordSys<T> result;
result.orientation=
#ifndef dont_normalize
Normalized
#endif
(c1.orientation*c2.orientation)
;
result.position=c1.orientation.Rotate(c2.position)+c1.position;
};

// transforms vector like 4x4 matrix would
template<class T>
Vec3<T> operator*(const CoordSys<T> &c,const Vec3<T> &v)
{
return c.orientation.rotate(v) + c.position;
};


template<class T>
CoordSys<T> Inverse(const CoordSys<T> &c1)
{
CoordSys<T> result;

// for rotation quaternions, signs do not matter
// (Q and -Q works the same). So i use minus conjugate,
// because it negates real part only and is
// faster than conjugate
result.orientation=MinusConjugate(c1.orientation);

result.position= -(result.orientation.rotate(c1.position));
return result;
};
template<class T>
inline Matrix4x4<T> TransformFrom(const CoordSys<T> &c1)
{
Matrix4x4<T> result(QuaternionToMatrix(c1.orientation));
result.a[0][3]=c1.position.x;
result.a[1][3]=c1.position.y;
result.a[2][3]=c1.position.z;
return result;
};
template<class T>
inline Matrix4x4<T> TransformTo(const CoordSys<T> &c1)
{
return TransformFrom(Inverse(c1));
};





The TransformFrom and TransformTo is used to get matrix for use in openGL.
How it is related:
To find "how CoordSys C2 looks from other CoordSys C1" (i assume that's what you want), i'd just use C2*Inverse(C1)
(if it would be really really speed critical and compiler wouldn't optimize everything out, i would maybe write it manually. But in any other case it's allright to work with CoordSys and not it's implementation details)

It's especially good when there's something complicated you has to do. It could be also good if you have code that used 4x4 matrices, or have experience using them. Also it hides details of implementation of coordinate system in a way that really makes sense (you may for example have CoordSysM that is implemented as 4x4 matrix , but is exactly same in usage)

Share this post


Link to post
Share on other sites
Quote:
Original post by Dmytry
Somewhat offtopic but possibly useful info on quats:

I wrote the 'coordinate system' class that is mostly equivalent in usage to 4x4 matrix (can be multiplied, etc) but has quaternion and vector inside (quaternion for rotation, vector for translation). It's very convenient for doing things like that.

Explanations of how you can figure out what to do with quaternions:

The basic idea of this is very simple, mostly same as with 3x3 matrix for rotation and vector for translation.
Let's first define
Q rotate V = Q*V*~Q , in other words, rotation of vector by quaternion. In programming it can be written as Q.rotate(V)
This "rotate" is much like rotation_matrix*vector, in that it also does rotation, and all properties of rotation apply.
For instance,
1.) Q rotate (V1+V2) = (Q rotate V1) + (Q rotate V2)
2.) Q1 rotate (Q2 rotate V) = (Q1*Q2) rotate V
3.) (~Q) rotate (Q rotate V) = V
The "rotate" is really sorta multiplication & from now on i will assume it have same precedence. These formulas can all be derived from definition of "rotate"

Now, we can define Euclidean transform(?) i.e. rotation and translation, as
E=(Q, P)
where P is translation and Q is quaternion. We can make it behave just like 4x4 matrix. We can define E*V to mean rotation&translation of V by E just as if E would be an 4x4 matrix, define ~E as inverse transform, and define E1*E2 as concatenated rotations.

So we have:
V' = E*V = (Q rotate V) + P , where Q is rotation and P is translation.
The inverse transform can be easily found as
V' = (Q rotate V) + P
V' - P = Q rotate V
~Q rotate (V' - P) = V
~Q rotate V' - ~Q rotate P = V

That is, for
E=(Q,P)
inverse is
~E=(~Q, - (~Q rotate P))

Another thing we can be interested in is concatenation of transformations. Say V is transformed by E1 then by E2 .
(E2*E1)*V = P2+Q2 rotate (P1+Q1 rotate V) = P2 + Q2 rotate P1 + Q2*Q1 rotate V
So we have
E2*E1=(Q2*Q1,P2 + Q2 rotate P1)


There is the code i use (somewhat crude), may be more readable than math above:
*** Source Snippet Removed ***
The TransformFrom and TransformTo is used to get matrix for use in openGL.
How it is related:
To find "how CoordSys C2 looks from other CoordSys C1" (i assume that's what you want), i'd just use C2*Inverse(C1)
(if it would be really really speed critical and compiler wouldn't optimize everything out, i would maybe write it manually. But in any other case it's allright to work with CoordSys and not it's implementation details)

It's especially good when there's something complicated you has to do. It could be also good if you have code that used 4x4 matrices, or have experience using them. Also it hides details of implementation of coordinate system in a way that really makes sense (you may for example have CoordSysM that is implemented as 4x4 matrix , but is exactly same in usage)



That's exactly the class I wanted to do. :) 'seems I gained time... ;)

Share this post


Link to post
Share on other sites

This topic is 4333 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this