# quaternion conundrum [SOLVED by Tepi]

2 replies to this topic

### #1 skullnbones

skullnbones

Light Bright

• New Member
• 104 posts
• Version:GM8

Posted 23 March 2011 - 05:22 PM

Basically I need to affect a point the same way this does:
d3d_transform__rotation_axis()
using the same arguments.

If been working with the psuedo code found here.
But it did not work the same.

//quaternion multiplication
Quaternion quat_mult(Quaternion q1, Quaternion q2)
{
Quaternion result;
result.a = (q1.a*q2.a -q1.b*q2.b -q1.c*q2.c -q1.d*q2.d);
result.b = (q1.a*q2.b +q1.b*q2.a +q1.c*q2.d -q1.d*q2.c);
result.c = (q1.a*q2.c -q1.b*q2.d +q1.c*q2.a +q1.d*q2.b);
result.d = (q1.a*q2.d +q1.b*q2.c -q1.c*q2.b +q1.d*q2.a);
return result;
}

//Quaternion multiplication without the .a component
Point quat_pointmult( Quaternion q1, Quaternion q2)
{
Point result;
result.x = (q1.a*q2.b +q1.b*q2.a +q1.c*q2.d -q1.d*q2.c);
result.y = (q1.a*q2.c -q1.b*q2.d +q1.c*q2.a +q1.d*q2.b);
result.z = (q1.a*q2.d +q1.b*q2.c -q1.c*q2.b +q1.d*q2.a);

return result;
}

//Uses quaternion mathematics to perform a rotation
Point quat_rot(Point point,Point rotVec,double angle)
{
double sinCoeff;
Quaternion rotQuat;
Quaternion pointQuat;
Quaternion conjQuat;
Quaternion temp;

sinCoeff=sin(angle*0.5);

rotQuat.a = cos(angle*0.5);

rotQuat.b=sinCoeff*rotVec.x;
rotQuat.c=sinCoeff*rotVec.y;
rotQuat.d=sinCoeff*rotVec.z;

pointQuat.a =0;
pointQuat.b = point.x;
pointQuat.c = point.y;
pointQuat.d = point.z;
//calculate conjugate of the quaternion
conjQuat.a = rotQuat.a;
conjQuat.b = -rotQuat.b;
conjQuat.c = -rotQuat.c;
conjQuat.d = -rotQuat.d;

//perform  rotation
temp=quat_mult(rotQuat,pointQuat);
return quat_pointmult(temp,conjQuat);

}


but this collapsed everything to roughly<2 degrees of freedom.

Then I tried normalizing the axis without the angle and still did

not get the result I was after (It still scaled things on me too).

The Wiki also mentions keeping things accurate by noting the

magnitude of the quaternion, but gives no hint as to how to apply

it:

The "quality" of the multiplication under approximate arithmetic

(such as floating point) could be retained by using quat_mult

instead of quat_pointmult and noting the magnitude of the .a

component of the resultant quaternion.

Has anyone figured out how Game Maker is performing this operation?

Edited by skullnbones, 06 April 2011 - 02:37 PM.

• 0

### #2 Tepi

Tepi

GMC Member

• Global Moderators
• 4201 posts
• Version:GM8.1

Posted 23 March 2011 - 05:49 PM

$\begin{bmatrix} x_{rotated}\\y_{rotated}\\z_{rotated}\end{bmatrix}$ = ,
where the axis is (u,v,w), the original point (x,y,z), and the angle θ.
• 1

### #3 skullnbones

skullnbones

Light Bright

• New Member
• 104 posts
• Version:GM8

Posted 24 March 2011 - 02:47 PM

...

Thanks alot Tepi! I've added you to the credits for the next 'Baked' release (05a).

Edit:

I've uploaded an example (be sure to precalculate the trig if you use this in a loop)
of the formula in action. Press f4 to go to full screen or else you will not be able to see anything.
The code used to generate the quaternion was provided by '1101'(also getting credit in the next release of Baked)

the green dot is at the origin and will not move. the blue and red start in the same position.
Rotate the blue dot with x y and z, hold shift to reverse.
Pressing u will apply the rotation of the blue dot to the red dot.
blue dot == d3d transforms
red dot == direct transform

formula coded is in object quat_point_raw in event key release 'U'

requires GM8pro

edit2: Ha! was 9 years off the date!

Edited by skullnbones, 06 April 2011 - 03:17 PM.

• 0

#### 0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users