Sign in to follow this  
Doublefris

Quaternions products not preserving length

Recommended Posts

Doublefris    316

Hello there, I want to multipy two quaternions as to rotate them.

 

I read http://www.songho.ca/math/quaternion/quaternion.html and found the formula for a length preserving rotation:

 

p * q * conj(p)

 

and tried to use this in my program.

however the magnitude of this result is not 1, while |p| and |q| are both 1.

What's going on? does this formula only work for preserving the vector part? And if so what is the proper way to multiply two quaternions represting rotations?

 

here is my multiplication function:

quaternion operator*( const quaternion& a, const quaternion& b )
{
	vec3 c = vecpart(a);
	vec3 d = vecpart(b);

	return quaternion(
		cross( c, d ) + (a.w * c) + (b.w * d),
		a.w*b.w - dot( c, d ));
}


and conj(q) = [scalar(q), -vector(q)]

 

thanks!

Share this post


Link to post
Share on other sites
alvaro    21246

You can always use [url="http://www.boost.org/doc/libs/1_41_0/libs/math/doc/quaternion/html/"]Boost.Quaternions[/url] to verify that your operations are correct.

 

EDIT: Or just use Boost.Quaternions instead of your own type. It works fine for me.

Edited by Álvaro

Share this post


Link to post
Share on other sites
Doublefris    316

cross( c, d ) + (a.w * c) + (b.w * d),

 

should be

 

cross( c, d ) + (a.w * d) + (b.w * c),

 

see:

 

687f7d10c9876d3194930482368f8df8.png

 

thanks, works perfectly :)

 

 

 

Alvaro I am just doing some small little project for experimentation, I don't really want to go and integrate boost with it:) thanks for the tip though.

Share this post


Link to post
Share on other sites
alvaro    21246

Alvaro I am just doing some small little project for experimentation, I don't really want to go and integrate boost with it:) thanks for the tip though.

 

All you need is [url="http://www.boost.org/doc/libs/1_41_0/boost/math/quaternion.hpp"]one header file[/url].

 

EDIT: Nevermind, that one includes a couple of other header files too. But it's still not too bad, since it's a header-file-only implementation.

Edited by Álvaro

Share this post


Link to post
Share on other sites
quasar3d    814

Checking if lengths are multiplictive (ie. the length of a product is equal to the product of the lengths) is actually a very good way to check if your quaternion multiplication works well (if it's multiplicative, your multiplication code is either correct or very wrong, but not a little bit wrong:)). So this was already quite a hint that there was a problem with your multiplication.

 

Note that for any quaternion a * conj(a) gives the square euclidean length, and so

 

|a * b|^2 = a * b * conj(a * b) = a * (b * conj(b)) * conj(a) = a * |b|^2 * conj(a) = a * conj(a) * |b|^2 = |a|^2 * |b|^2

Edited by quasar3d

Share this post


Link to post
Share on other sites

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