36 result.w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z;
37 result.x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y;
38 result.y = q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z;
39 result.z = q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x;
44#if !OOMATHS_STANDALONE
52 quaternion_normalize(quat);
70 xx = 2.0f *
x; yy = 2.0f *
y; zz = 2.0f * z;
71 wx = w * xx; wy = w * yy;
72 xx =
x * xx; xz =
x * zz;
73 yy =
y * yy; yz =
y * zz;
77 res.z = 1.0f - xx - yy;
79 if (res.x||res.y||res.z)
return vector_normal(res);
80 else return make_vector(0.0f, 0.0f, 1.0f);
102 xx = 2.0f *
x; yy = 2.0f *
y; zz = 2.0f * z;
103 wx = w * xx; wz = w * zz;
104 xx =
x * xx; xy =
x * yy;
109 res.y = 1.0f - xx - zz;
112 if (res.x||res.y||res.z)
return vector_normal(res);
113 else return make_vector(0.0f, 1.0f, 0.0f);
130 yy = 2.0f *
y; zz = 2.0f * z;
131 wy = w * yy; wz = w * zz;
132 xy =
x * yy; xz =
x * zz;
136 res.x = 1.0f - yy - zz;
140 if (res.x||res.y||res.z)
return vector_normal(res);
141 else return make_vector(1.0f, 0.0f, 0.0f);
157 xx = 2.0f *
x; yy = 2.0f *
y; zz = 2.0f * z;
158 wx = w * xx; wy = w * yy; wz = w * zz;
159 xx =
x * xx; xy =
x * yy; xz =
x * zz;
160 yy =
y * yy; yz =
y * zz;
163 if (outRight != NULL)
165 outRight->x = 1.0f - yy - zz;
166 outRight->y = xy - wz;
167 outRight->z = xz + wy;
169 if (outRight->x || outRight->y || outRight->z) *outRight = vector_normal(*outRight);
170 else *outRight = make_vector(1.0f, 0.0f, 0.0f);
176 outUp->y = 1.0f - xx - zz;
179 if (outUp->x || outUp->y || outUp->z) *outUp = vector_normal(*outUp);
180 else *outUp = make_vector(0.0f, 1.0f, 0.0f);
183 if (outForward != NULL)
185 outForward->x = xz - wy;
186 outForward->y = yz + wx;
187 outForward->z = 1.0f - xx - yy;
189 if (outForward->x || outForward->y || outForward->z) *outForward = vector_normal(*outForward);
190 else *outForward = make_vector(0.0f, 0.0f, 1.0f);
198 OOScalar s = sqrt((1.0f + v0.x * v1.x + v0.y * v1.y + v0.z * v1.z) * 2.0f);
202 q.x = (v0.y * v1.z - v0.z * v1.y) * is;
203 q.y = (v0.z * v1.x - v0.x * v1.z) * is;
204 q.z = (v0.x * v1.y - v0.y * v1.x) * is;
212 q = make_quaternion(0, 1, 0, 0);
229 OOHPScalar s = sqrt((1.0 + v0.x * v1.x + v0.y * v1.y + v0.z * v1.z) * 2.0);
233 q.x = (v0.y * v1.z - v0.z * v1.y) * is;
234 q.y = (v0.z * v1.x - v0.x * v1.z) * is;
235 q.z = (v0.x * v1.y - v0.y * v1.x) * is;
243 q = make_quaternion(0, 1, 0, 0);
260 OOScalar min_s = 2.0f * cosf(0.5f * maxArc);
261 OOScalar s = sqrtf((1.0f + v0.x * v1.x + v0.y * v1.y + v0.z * v1.z) * 2.0f);
270 q.x = (v0.y * v1.z - v0.z * v1.y) * scale;
271 q.y = (v0.z * v1.x - v0.x * v1.z) * scale;
272 q.z = (v0.x * v1.y - v0.y * v1.x) * scale;
278 q.x = (v0.y * v1.z - v0.z * v1.y) * is;
279 q.y = (v0.z * v1.x - v0.x * v1.z) * is;
280 q.z = (v0.x * v1.y - v0.y * v1.x) * is;
300 result.w = quat->w * w - quat->x * scale;
301 result.x = quat->w * scale + quat->x * w;
302 result.y = quat->y * w + quat->z * scale;
303 result.z = quat->z * w - quat->y * scale;
319 result.w = quat->w * w - quat->y * scale;
320 result.x = quat->x * w - quat->z * scale;
321 result.y = quat->w * scale + quat->y * w;
322 result.z = quat->z * w + quat->x * scale;
338 result.w = quat->w * w - quat->z * scale;
339 result.x = quat->x * w + quat->y * scale;
340 result.y = quat->y * w - quat->x * scale;
341 result.z = quat->w * scale + quat->z * w;
358 q2.x = axis.x * scale;
359 q2.y = axis.y * scale;
360 q2.z = axis.z * scale;
367NSString *QuaternionDescription(Quaternion quaternion)
372 x = fabsf(quaternion.x);
373 y = fabsf(quaternion.y);
374 z = fabsf(quaternion.z);
376 xs = (quaternion.x >= 0.0f) ?
'+' :
'-';
377 ys = (quaternion.y >= 0.0f) ?
'+' :
'-';
378 zs = (quaternion.z >= 0.0f) ?
'+' :
'-';
380 return [NSString stringWithFormat:@"(%g %c %gi %c %gj %c %gk)", quaternion.w, xs, x, ys, y, zs, z];
389 qv.w = 0.0f - q.x * v.x - q.y * v.y - q.z * v.z;
390 qv.x = -q.w * v.x + q.y * v.z - q.z * v.y;
391 qv.y = -q.w * v.y + q.z * v.x - q.x * v.z;
392 qv.z = -q.w * v.z + q.x * v.y - q.y * v.x;
394 v.x = qv.w * -q.x + qv.x * -q.w + qv.y * -q.z - qv.z * -q.y;
395 v.y = qv.w * -q.y + qv.y * -q.w + qv.z * -q.x - qv.x * -q.z;
396 v.z = qv.w * -q.z + qv.z * -q.w + qv.x * -q.y - qv.y * -q.x;
405 qvw = 0.0 - q.x * v.x - q.y * v.y - q.z * v.z;
406 qvx = -q.w * v.x + q.y * v.z - q.z * v.y;
407 qvy = -q.w * v.y + q.z * v.x - q.x * v.z;
408 qvz = -q.w * v.z + q.x * v.y - q.y * v.x;
410 v.x = qvw * -q.x + qvx * -q.w + qvy * -q.z - qvz * -q.y;
411 v.y = qvw * -q.y + qvy * -q.w + qvz * -q.x - qvx * -q.z;
412 v.z = qvw * -q.z + qvz * -q.w + qvx * -q.y - qvy * -q.x;
const HPVector kBasisZHPVector
Vector vector_up_from_quaternion(Quaternion quat)
void quaternion_rotate_about_x(Quaternion *quat, OOScalar angle)
HPVector HPvector_forward_from_quaternion(Quaternion quat)
Vector vector_right_from_quaternion(Quaternion quat)
Vector vector_forward_from_quaternion(Quaternion quat)
void basis_vectors_from_quaternion(Quaternion quat, Vector *outRight, Vector *outUp, Vector *outForward)
void quaternion_rotate_about_z(Quaternion *quat, OOScalar angle)
HPVector quaternion_rotate_HPvector(Quaternion q, HPVector v)
void quaternion_set_random(Quaternion *quat)
Vector quaternion_rotate_vector(Quaternion q, Vector v)
const Quaternion kIdentityQuaternion
Quaternion quaternion_rotation_between(Vector v0, Vector v1)
void quaternion_rotate_about_y(Quaternion *quat, OOScalar angle)
Quaternion quaternion_limited_rotation_between(Vector v0, Vector v1, float maxArc)
const Quaternion kZeroQuaternion
Quaternion quaternion_rotation_betweenHP(HPVector v0, HPVector v1)
void quaternion_rotate_about_axis(Quaternion *quat, Vector axis, OOScalar angle)
Quaternion quaternion_multiply(Quaternion q1, Quaternion q2)
const Vector kBasisZVector