7 Degrees yaw, pitch, roll;
12 double y = 2 * ( value.y*value.z + value.w*value.x );
13 if(fabs(y) <= 1.0 - 0.000005)
15 double x = 2 * ( value.x*value.z - value.w*value.y );
16 double z = 1 - 2 * ( value.x*value.x + value.y*value.y );
17 Angle yaw = -atan2(x, z);
18 Angle pitch = atan2(y, sqrt(x * x + z * z));
19 double sYaw = sin( yaw / 2 );
20 double cYaw = cos( yaw / 2 );
21 double sPitch = sin( pitch / 2 );
22 double cPitch = cos( pitch / 2 );
23 Quaternion yp = { cPitch * cYaw, sPitch * cYaw, cPitch * sYaw, sPitch * sYaw };
24 double rollW = yp.w * value.w + yp.x * value.x + yp.y * value.y + yp.z * value.z;
25 double rollZ = yp.w * value.z + yp.x * value.y - yp.y * value.x - yp.z * value.w;
29 this.roll = atan2(rollZ, rollW) * 2;
33 // 90 degrees pitch case
34 double sin45 = sin(Pi/4);
35 double yawW = sin45 * value.w + sin45 * value.x;
36 double yawY = sin45 * value.y + sin45 * value.z;
38 this.yaw = atan2(yawY, yawW) * 2;
45 double sYaw = sin( yaw / 2 );
46 double cYaw = cos( yaw / 2 );
47 double sPitch = sin( pitch / 2 );
48 double cPitch = cos( pitch / 2 );
49 double sRoll = sin( roll / 2 );
50 double cRoll = cos( roll / 2 );
51 Quaternion yp = { cPitch * cYaw, sPitch * cYaw, cPitch * sYaw, sPitch * sYaw };
53 value.w = yp.w * cRoll - yp.z * sRoll;
54 value.x = yp.x * cRoll - yp.y * sRoll;
55 value.y = yp.y * cRoll + yp.x * sRoll;
56 value.z = yp.z * cRoll + yp.w * sRoll;
60 void Add(Euler e1, Euler e2)
62 yaw = e1.yaw + e2.yaw;
63 pitch = e1.pitch + e2.pitch;
64 roll = e1.roll + e2.roll;
68 public struct Quaternion
78 void Normalize(Quaternion source)
80 double m = sqrt(source.x * source.x +
87 x = (double)(source.x/m);
88 y = (double)(source.y/m);
89 z = (double)(source.z/m);
90 w = (double)(source.w/m);
96 void Multiply(Quaternion q1, Quaternion q2)
98 w = q1.w * q2.w - q2.x * q1.x - q1.y * q2.y - q1.z * q2.z;
99 x = q1.w * q2.x + q2.w * q1.x + q1.y * q2.z - q1.z * q2.y;
100 y = q1.w * q2.y + q2.w * q1.y + q1.z * q2.x - q1.x * q2.z;
101 z = q1.w * q2.z + q2.w * q1.z + q1.x * q2.y - q1.y * q2.x;
104 void Divide(Quaternion q1, Quaternion q2)
106 w = q2.w * q1.w + q2.x * q1.x + q2.y * q1.y + q2.z * q1.z;
107 x = q2.w * q1.x - q2.x * q1.w + q2.y * q1.z - q2.z * q1.y;
108 y = q2.w * q1.y - q2.x * q1.z - q2.y * q1.w + q2.z * q1.x;
109 z = q2.w * q1.z + q2.x * q1.y - q2.y * q1.x - q2.z * q1.w;
112 void RotationAxis(Vector3D axis, Degrees angle)
114 double sa = sin( angle / 2 );
115 double ca = cos( angle / 2 );
123 void RotationYawPitchRoll(Euler euler)
125 Quaternion rotation, result;
127 result.Yaw(euler.yaw);
128 rotation.Pitch(euler.pitch);
129 Multiply(rotation, result);
130 rotation.Roll(euler.roll);
131 result.Multiply(rotation, this);
135 void RotationDirection(Vector3D direction)
137 Angle yaw = -atan2(direction.x, direction.z);
138 Angle pitch = atan2(direction.y, sqrt(direction.x * direction.x + direction.z * direction.z));
139 YawPitch(yaw, pitch);
142 void RotationMatrix(Matrix m)
144 double t = m.m[0][0] + m.m[1][1] + m.m[2][2] + 1.0;
147 double s = sqrt(t) * 2;
149 w = (double) (0.25f * s);
150 x = (double) (( m.m[2][1] - m.m[1][2] ) / s);
151 y = (double) (( m.m[0][2] - m.m[2][0] ) / s);
152 z = (double) (( m.m[1][0] - m.m[0][1] ) / s);
161 int nxt[3] = {1,2,0};
162 if(m.m[1][1] > m.m[0][0]) i = 1;
163 if(m.m[2][2] > m.m[i][i]) i = 2;
166 s = sqrt(m.m[i][i] - (m.m[j][j] + m.m[k][k]) + 1.0) * 2;
168 w = (double) ((m.m[k][j] - m.m[j][k]) / s);
170 q[i] = (double) (0.25f * s);
171 q[j] = (double) ((m.m[j][i] - m.m[i][j]) / s);
172 q[k] = (double) ((m.m[k][i] - m.m[i][k]) / s);
182 void Slerp(Quaternion from, Quaternion to, float t)
185 double omega, cosom, sinom, scale0, scale1;
187 cosom = from.x * to.x + from.y * to.y + from.z * to.z + from.w * to.w;
205 if ( (1.0 - cosom) > DELTA )
209 scale0 = sin((1.0 - t) * omega) / sinom;
210 scale1 = sin(t * omega) / sinom;
218 x = (double)(scale0 * from.x + scale1 * to1[0]);
219 y = (double)(scale0 * from.y + scale1 * to1[1]);
220 z = (double)(scale0 * from.z + scale1 * to1[2]);
221 w = (double)(scale0 * from.w + scale1 * to1[3]);
224 void Yaw(Degrees angle)
226 double sa = sin( angle / 2 );
227 double ca = cos( angle / 2 );
235 void YawPitch(Degrees yaw, Degrees pitch)
237 double sYaw = sin( yaw / 2 );
238 double cYaw = cos( yaw / 2 );
239 double sPitch = sin( pitch / 2 );
240 double cPitch = cos( pitch / 2 );
248 void Pitch(Degrees angle)
250 double sa = sin( angle / 2 );
251 double ca = cos( angle / 2 );
259 void Roll(Degrees angle)
261 double sa = sin( angle / 2 );
262 double ca = cos( angle / 2 );
270 void RotatePitch(Degrees pitch)
272 Quaternion rotation, result;
274 rotation.Pitch(pitch);
275 result.Multiply(rotation, this);
279 void RotateYaw(Degrees yaw)
281 Quaternion rotation, result;
283 result.Multiply(rotation, this);
287 void RotateRoll(Degrees roll)
289 Quaternion rotation, result;
292 result.Multiply(rotation, this);
296 void RotateYawPitch(Degrees yaw, Degrees pitch)
298 Quaternion rotation, result;
299 rotation.YawPitch(yaw, pitch);
300 result.Multiply(rotation, this);
304 void ToDirection(Vector3D direction)
307 Vector3Df vector { 0,0,1 };
309 mat.RotationQuaternion(this);
310 direction.Transform(vector, mat);
312 direction.x = (double)( 2 * ( x*z - w*y ));
313 direction.y = (double)( 2 * ( y*z + w*x ));
314 direction.z = (double)(1 - 2 * ( x*x + y*y ));
317 void Inverse(Quaternion source)
319 this = { -source.w, source.x, source.y, source.z };