Sign in to follow this  
ms75214

quaternion subtraction

Recommended Posts

I'm trying to understand quaternion subtraction, so I wrote the following small test:



//Convert radians to degrees
#define RTOD(r) ((r) * 180 / M_PI)


//Convert degrees to radians
#define DTOR(d) ((d) * M_PI / 180)




void subtractTest(void)
{
D3DXQUATERNION angle45, angle35;

D3DXQuaternionRotationYawPitchRoll(&angle45, 0, 0, DTOR(45));
D3DXQuaternionRotationYawPitchRoll(&angle35, 0, 0, DTOR(35));

D3DXQUATERNION angle10;
angle10=angle45-angle35;

FLOAT w;
D3DXVECTOR3 axis;
D3DXQuaternionToAxisAngle(&angle10,&axis,&w);
float resultAngle = RTOD(w);

}



It tries to take a 45 degree angle and subtract a 35 degree angle from it. I would think the result would be a 10 degree angle, but
it's not. It turns out to be about 183 degrees. Any ideas why I'm not getting a 10 degree angle as the result?

Share this post


Link to post
Share on other sites
You need to multiply quaternions to get successive changes in angle, not subtract them.

E.g., a quaternion for a y-axis rotation of +45 degrees times a quaternion for a y-axis rotation of -35 degrees gives you a quaternion for a y-axis rotation of 10 degrees.

Share this post


Link to post
Share on other sites
Quote:
Original post by Buckeye
You need to multiply quaternions to get successive changes in angle, not subtract them.

E.g., a quaternion for a y-axis rotation of +45 degrees times a quaternion for a y-axis rotation of -35 degrees gives you a quaternion for a y-axis rotation of 10 degrees.


Well, he has a rotation of +45 degrees and a rotation of +35 degrees, so he probably wants to divide them.

Share this post


Link to post
Share on other sites
Quote:
Original post by alvaro
Quote:
Original post by Buckeye
You need to multiply quaternions to get successive changes in angle, not subtract them.

E.g., a quaternion for a y-axis rotation of +45 degrees times a quaternion for a y-axis rotation of -35 degrees gives you a quaternion for a y-axis rotation of 10 degrees.


Well, he has a rotation of +45 degrees and a rotation of +35 degrees, so he probably wants to divide them.


I tried this:

angle10=angle45/angle35;

I got this error:

Error 22 error C2679: binary '/' : no operator found which takes a right-hand operand of type 'D3DXQUATERNION' (or there is no acceptable conversion)

I don't think DirectX supports quaternion division.

Share this post


Link to post
Share on other sites
Quote:
angle10=angle45/angle35;

That makes no sense, I'm afraid. What happened when you tried multiplication as I suggested (using -35 instead of +35)?

Share this post


Link to post
Share on other sites
Quote:
Original post by Buckeye
Quote:
angle10=angle45/angle35;

That makes no sense, I'm afraid. What happened when you tried multiplication as I suggested (using -35 instead of +35)?


Ok. This seems to do roughly what I was trying to do:

D3DXQUATERNION angleNeg35;
D3DXQuaternionInverse(&angleNeg35, &angle35);

angle10=angle45*angleNeg35;

Here's the full code:

void subtractTest(void)
{
D3DXQUATERNION angle45, angle35;

D3DXQuaternionRotationYawPitchRoll(&angle45, 0, 0, DTOR(45));
D3DXQuaternionRotationYawPitchRoll(&angle35, 0, 0, DTOR(35));

D3DXQUATERNION angle10;

D3DXQUATERNION angleNeg35;
D3DXQuaternionInverse(&angleNeg35, &angle35);

angle10=angle45*angleNeg35;

FLOAT w;
D3DXVECTOR3 axis;
D3DXQuaternionToAxisAngle(&angle10,&axis,&w);
float resultAngle = RTOD(w);

}

Share this post


Link to post
Share on other sites
Quote:
Original post by Buckeye
Quote:
angle10=angle45/angle35;

That makes no sense, I'm afraid. What happened when you tried multiplication as I suggested (using -35 instead of +35)?


Why do you think it makes no sense? It might be that Direct3D's quaternion implementation doesn't overload the / operator, but mathematically it makes perfect sense.

#include <iostream>
#include <cmath>
#include <boost/math/quaternion.hpp>

typedef boost::math::quaternion<double> Q;

const double deg = std::atan(1.0)/45.0;
int main() {
Q a(std::cos(45*deg/2), 0, std::sin(45*deg/2), 0);
Q b(std::cos(35*deg/2), 0, std::sin(35*deg/2), 0);

Q c = a / b;

std::cout << c << '\n';
}



Share this post


Link to post
Share on other sites
Quote:
It might be that Direct3D's quaternion implementation doesn't overload the / operator, but mathematically it makes perfect sense.

It's the former I was commenting on. I actually checked the docs to see if / were overloaded.

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