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?
quaternion subtraction
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.
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.
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 alvaroQuote: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)?
Quote:Original post by BuckeyeQuote: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 BuckeyeQuote: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.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement