quaternion subtraction

Started by
6 comments, last by Buckeye 13 years, 5 months ago
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?

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

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

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.
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.
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)?

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

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);

}
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';}

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.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

This topic is closed to new replies.

Advertisement