Sign in to follow this  

quaternion subtraction

This topic is 2590 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

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:
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

This topic is 2590 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