ms75214 143 Report post Posted November 12, 2010 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, butit's not. It turns out to be about 183 degrees. Any ideas why I'm not getting a 10 degree angle as the result? 0 Share this post Link to post Share on other sites
Buckeye 10747 Report post Posted November 12, 2010 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. 0 Share this post Link to post Share on other sites
alvaro 21272 Report post Posted November 12, 2010 Quote:Original post by BuckeyeYou 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. 0 Share this post Link to post Share on other sites
ms75214 143 Report post Posted November 12, 2010 Quote:Original post by alvaroQuote:Original post by BuckeyeYou 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. 0 Share this post Link to post Share on other sites
Buckeye 10747 Report post Posted November 12, 2010 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)? 0 Share this post Link to post Share on other sites
ms75214 143 Report post Posted November 12, 2010 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);} 0 Share this post Link to post Share on other sites
alvaro 21272 Report post Posted November 12, 2010 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';} 0 Share this post Link to post Share on other sites
Buckeye 10747 Report post Posted November 12, 2010 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. 0 Share this post Link to post Share on other sites