CUGL 1.1
Cornell University Game Library
CUQuaternion.h
1 //
2 // CUQuaternion.h
3 // Cornell University Game Library (CUGL)
4 //
5 // This module provides support for a quaternion, which is a way of representing
6 // rotations in 3d sapce.. It has support for basic arithmetic, as well as
7 // as the standard quaternion interpolations.
8 //
9 // Because math objects are intended to be on the stack, we do not provide
10 // any shared pointer support in this class.
11 //
12 // This module is based on an original file from GamePlay3D: http://gameplay3d.org.
13 // It has been modified to support the CUGL framework.
14 //
15 // CUGL zlib License:
16 // This software is provided 'as-is', without any express or implied
17 // warranty. In no event will the authors be held liable for any damages
18 // arising from the use of this software.
19 //
20 // Permission is granted to anyone to use this software for any purpose,
21 // including commercial applications, and to alter it and redistribute it
22 // freely, subject to the following restrictions:
23 //
24 // 1. The origin of this software must not be misrepresented; you must not
25 // claim that you wrote the original software. If you use this software
26 // in a product, an acknowledgment in the product documentation would be
27 // appreciated but is not required.
28 //
29 // 2. Altered source versions must be plainly marked as such, and must not
30 // be misrepresented as being the original software.
31 //
32 // 3. This notice may not be removed or altered from any source distribution.
33 //
34 // Author: Walker White
35 // Version: 6/5/16
36 #ifndef __CU_QUATERNION_H__
37 #define __CU_QUATERNION_H__
38 
39 #include <math.h>
40 #include "CUVec3.h"
41 #include "CUMathBase.h"
42 
43 namespace cugl {
44 
45 // Forward declarations
46 class Mat4;
47 
97 class Quaternion {
98 
99 #pragma mark Values
100 public:
102  float x;
104  float y;
106  float z;
108  float w;
109 
111  static const Quaternion ZERO;
113  static const Quaternion IDENTITY;
114 
115 
116 #pragma mark -
117 #pragma mark Constructors
118 public:
122  Quaternion() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) {}
123 
132  Quaternion(float x, float y, float z, float w) {
133  this->x = x; this->y = y; this->z = z; this->w = w;
134  }
135 
143  Quaternion(float* array);
144 
151  Quaternion(const Vec3& axis, float angle);
152 
153 
154 #pragma mark -
155 #pragma mark Static Constructors
156 
166  static Quaternion* createFromRotationMatrix(const Mat4& m, Quaternion* dst);
167 
179  static Quaternion* createFromAxisAngle(const Vec3& axis, float angle, Quaternion* dst);
180 
181 
182 #pragma mark -
183 #pragma mark Setters
184 
193  Quaternion& operator=(const float* array) {
194  return set(array);
195  }
196 
207  Quaternion& set(float x, float y, float z, float w) {
208  this->x = x; this->y = y; this->z = z; this->w = w;
209  return *this;
210  }
211 
221  Quaternion& set(const float* array);
222 
231  Quaternion& set(const Vec3& axis, float angle);
232 
240  Quaternion& set(const Quaternion& q) {
241  x = q.x; y = q.y; z = q.z; w = q.w;
242  return *this;
243  }
244 
251  x = y = z = 0; w = 1;
252  return *this;
253  }
254 
261  x = y = z = w = 0;
262  return *this;
263  }
264 
265 
266 #pragma mark -
267 #pragma mark Static Arithmetic
268 
277  static Quaternion* add(const Quaternion& q1, const Quaternion& q2, Quaternion* dst);
278 
288  static Quaternion* subtract(const Quaternion& q1, const Quaternion& q2, Quaternion* dst);
289 
301  static Quaternion* multiply(const Quaternion& q1, const Quaternion& q2, Quaternion* dst);
302 
315  static Quaternion* divide(const Quaternion& q1, const Quaternion& q2, Quaternion* dst);
316 
326  static Quaternion* scale(const Quaternion& q1, float s, Quaternion* dst);
327 
336  static Quaternion* conjugate(const Quaternion& quat, Quaternion* dst);
337 
354  static Quaternion* invert(const Quaternion& quat, Quaternion* dst);
355 
367  static Quaternion* normalize(const Quaternion& quat, Quaternion* dst);
368 
377  static Quaternion* negate(const Quaternion& quat, Quaternion* dst);
378 
387  static float dot(const Quaternion& q1, const Quaternion& q2) {
388  return (q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w);
389  }
390 
391 
392 #pragma mark -
393 #pragma mark Arithmetic
394 
401  Quaternion& add(const Quaternion& q) {
402  x += q.x; y += q.y; z += q.z; w += q.w;
403  return *this;
404  }
405 
414  x -= q.x; y -= q.y; z -= q.z; w -= q.w;
415  return *this;
416  }
417 
426  return *(multiply(*this,q,this));
427  }
428 
429 
440  return *(divide(*this,q,this));
441  }
442 
443 
451  Quaternion& scale(float s) {
452  x *= s; y *= s; z *= s; w *= s;
453  return *this;
454  }
455 
462  x = -x; y = -y; z = -z;
463  return *this;
464  }
465 
472  Quaternion result;
473  return *(conjugate(*this,&result));
474  }
475 
490  return *(invert(*this,this));
491  }
492 
507  Quaternion result;
508  return *(invert(*this,&result));
509  }
510 
520  return *(normalize(*this,this));
521  }
522 
534  Quaternion result;
535  return *(normalize(*this,&result));
536  }
537 
544  x = -x; y = -y; z = -z; w = -w;
545  return *this;
546  }
547 
556  Quaternion result;
557  return *(negate(*this,&result));
558  }
559 
567  float dot(const Quaternion& q) const {
568  return (x * q.x + y * q.y + z * q.z + w * q.w);
569  }
570 
571 
572 
573 #pragma mark -
574 #pragma mark Operators
575 
583  return add(q);
584  }
585 
594  return subtract(q);
595  }
596 
604  Quaternion& operator*=(float s) {
605  return scale(s);
606  }
607 
618  return *(multiply(*this,q,this));
619  }
620 
628  Quaternion& operator/=(float s) {
629  return *(scale(*this,1.0f/s,this));
630  }
631 
644  return *(divide(*this,q,this));
645  }
646 
656  const Quaternion operator+(const Quaternion& q) const {
657  Quaternion result;
658  return *(add(*this,q,&result));
659  }
660 
670  const Quaternion operator-(const Quaternion& q) const {
671  Quaternion result;
672  return *(subtract(*this,q,&result));
673  }
674 
682  const Quaternion operator-() const {
683  Quaternion result;
684  return *(negate(*this,&result));
685  }
686 
696  const Quaternion operator*(float s) const {
697  Quaternion result;
698  return *(scale(*this,s,&result));
699  }
700 
712  const Quaternion operator*(const Quaternion& q) const {
713  Quaternion result;
714  return *(multiply(*this,q,&result));
715  }
716 
726  const Quaternion operator/(float s) const {
727  Quaternion result;
728  return *(scale(*this,1.0f/s,&result));
729  }
730 
744  const Quaternion operator/(const Quaternion& q) const {
745  Quaternion result;
746  return *(divide(*this,q,&result));
747  }
748 
749 
750 #pragma mark -
751 #pragma mark Comparisons
752 
762  bool operator==(const Quaternion& q) const {
763  return x == q.x && y == q.y && z == q.z && w == q.w;
764  }
765 
776  bool operator!=(const Quaternion& q) const {
777  return x != q.x || y != q.y || z != q.z || w != q.w;
778  }
779 
791  bool equals(const Quaternion& q, float variance=CU_MATH_EPSILON) const {
792  return (*this-q).normSquared() < variance*variance;
793  }
794 
795 #pragma mark -
796 #pragma mark Linear Attributes
797 
804  float norm() const {
805  return sqrt(normSquared());
806  }
807 
820  float normSquared() const {
821  return x*x+y*y+z*z+w*w;
822  }
823 
832  bool isZero() const {
833  return x == 0.0f && y == 0.0f && z == 0.0f && w == 0.0f;
834  }
835 
845  bool isNearZero(float variance=CU_MATH_EPSILON) const {
846  return normSquared() < variance*variance;
847  }
848 
854  bool isIdentity() const {
855  return x == 0.0f && y == 0.0f && z == 0.0f && w == 1.0f;
856  }
857 
867  bool isNearIdentity(float variance=CU_MATH_EPSILON) const {
868  return equals(IDENTITY,variance);
869  }
870 
878  bool isUnit(float variance=CU_MATH_EPSILON) const {
879  float dot = norm()-1.0f;
880  return fabsf(dot) <= variance;
881  }
882 
892  float toAxisAngle(Vec3* e) const;
893 
894 
895 #pragma mark -
896 #pragma mark Static Interpolation
897 
913  static Quaternion* lerp(const Quaternion& q1, const Quaternion& q2, float t, Quaternion* dst);
914 
935  static Quaternion* slerp(const Quaternion& q1, const Quaternion& q2, float t, Quaternion* dst);
936 
957  static Quaternion* nlerp(const Quaternion& q1, const Quaternion& q2, float t, Quaternion* dst);
958 
970  static Vec3* rotate(const Vec3& v, const Quaternion& quat, Vec3* dst);
971 
972 
973 #pragma mark -
974 #pragma mark Interpolation
975 
989  Quaternion& lerp(const Quaternion& q, float t) {
990  return *(lerp(*this,q,t,this));
991  }
992 
1011  Quaternion& slerp(const Quaternion& q, float t) {
1012  return *(slerp(*this,q,t,this));
1013  }
1014 
1033  Quaternion& nlerp(const Quaternion& q, float t) {
1034  return *(slerp(*this,q,t,this));
1035  }
1036 
1053  Quaternion getLerp(const Quaternion& q, float t) {
1054  Quaternion result;
1055  return *(lerp(*this,q,t,&result));
1056  }
1057 
1078  Quaternion getSlerp(const Quaternion& q, float t) {
1079  Quaternion result;
1080  return *(slerp(*this,q,t,&result));
1081  }
1082 
1103  Quaternion getNlerp(const Quaternion& q, float t) {
1104  Quaternion result;
1105  return *(nlerp(*this,q,t,&result));
1106  }
1107 
1116  Vec3 getRotation(const Vec3& v) {
1117  Vec3 result;
1118  return *(rotate(v,*this,&result));
1119  }
1120 
1121 #pragma mark -
1122 #pragma mark Conversion Methods
1123 public:
1134  std::string toString(bool verbose = false) const;
1135 
1137  operator std::string() const { return toString(); }
1138 
1140  operator Vec4() const;
1141 
1147  explicit Quaternion(const Vec4& vector);
1148 
1156  Quaternion& operator= (const Vec4& vector) {
1157  return set(vector);
1158  }
1159 
1167  Quaternion& set(const Vec4& vector);
1168 
1175  operator Mat4() const;
1176 
1186  explicit Quaternion(const Mat4& m);
1187 
1200  return set(m);
1201  }
1202 
1214  Quaternion& set(const Mat4& m);
1215 
1216 };
1217 
1230 inline Vec3& operator*=(Vec3& v, const Quaternion& quat) {
1231  return *(Quaternion::rotate(v,quat,&v));
1232 }
1233 
1246 inline const Vec3 operator*(const Vec3& v, const Quaternion& quat) {
1247  Vec3 result;
1248  return *(Quaternion::rotate(v,quat,&result));
1249 }
1250 
1260 inline const Quaternion operator*(float s, const Quaternion& quat) {
1261  Quaternion result;
1262  return *(Quaternion::scale(quat,s,&result));
1263 }
1264 
1265 
1266 }
1267 
1268 #endif /* __CU_QUATERNION_H__ */
Quaternion & lerp(const Quaternion &q, float t)
Definition: CUQuaternion.h:989
std::string toString(bool verbose=false) const
bool operator==(const Quaternion &q) const
Definition: CUQuaternion.h:762
const Quaternion operator*(const Quaternion &q) const
Definition: CUQuaternion.h:712
Quaternion getNegation() const
Definition: CUQuaternion.h:555
const Quaternion operator-() const
Definition: CUQuaternion.h:682
Quaternion getConjugate() const
Definition: CUQuaternion.h:471
Vec2 & operator*=(Vec2 &v, const Affine2 &m)
Definition: CUAffine2.h:1165
Quaternion & multiply(const Quaternion &q)
Definition: CUQuaternion.h:425
static Quaternion * subtract(const Quaternion &q1, const Quaternion &q2, Quaternion *dst)
Quaternion & set(const Quaternion &q)
Definition: CUQuaternion.h:240
Quaternion & operator*=(float s)
Definition: CUQuaternion.h:604
static Quaternion * createFromAxisAngle(const Vec3 &axis, float angle, Quaternion *dst)
float normSquared() const
Definition: CUQuaternion.h:820
static Quaternion * lerp(const Quaternion &q1, const Quaternion &q2, float t, Quaternion *dst)
static float dot(const Quaternion &q1, const Quaternion &q2)
Definition: CUQuaternion.h:387
Quaternion()
Definition: CUQuaternion.h:122
bool equals(const Quaternion &q, float variance=CU_MATH_EPSILON) const
Definition: CUQuaternion.h:791
Quaternion & operator/=(const Quaternion &q)
Definition: CUQuaternion.h:643
float dot(const Quaternion &q) const
Definition: CUQuaternion.h:567
Quaternion & subtract(const Quaternion &q)
Definition: CUQuaternion.h:413
const Quaternion operator*(float s) const
Definition: CUQuaternion.h:696
Quaternion & operator*=(const Quaternion &q)
Definition: CUQuaternion.h:617
Quaternion & negate()
Definition: CUQuaternion.h:543
float norm() const
Definition: CUQuaternion.h:804
Quaternion & set(float x, float y, float z, float w)
Definition: CUQuaternion.h:207
static Quaternion * nlerp(const Quaternion &q1, const Quaternion &q2, float t, Quaternion *dst)
bool isIdentity() const
Definition: CUQuaternion.h:854
static Vec3 * rotate(const Vec3 &v, const Quaternion &quat, Vec3 *dst)
Quaternion & slerp(const Quaternion &q, float t)
Definition: CUQuaternion.h:1011
bool isNearIdentity(float variance=CU_MATH_EPSILON) const
Definition: CUQuaternion.h:867
Quaternion & operator+=(const Quaternion &q)
Definition: CUQuaternion.h:582
Quaternion & operator=(const float *array)
Definition: CUQuaternion.h:193
bool isNearZero(float variance=CU_MATH_EPSILON) const
Definition: CUQuaternion.h:845
bool isZero() const
Definition: CUQuaternion.h:832
float x
Definition: CUQuaternion.h:102
static Quaternion * add(const Quaternion &q1, const Quaternion &q2, Quaternion *dst)
static const Quaternion IDENTITY
Definition: CUQuaternion.h:113
const Quaternion operator/(const Quaternion &q) const
Definition: CUQuaternion.h:744
Quaternion & scale(float s)
Definition: CUQuaternion.h:451
Quaternion & divide(const Quaternion &q)
Definition: CUQuaternion.h:439
float w
Definition: CUQuaternion.h:108
float y
Definition: CUQuaternion.h:104
Definition: CUVec4.h:73
Quaternion & normalize()
Definition: CUQuaternion.h:519
bool operator!=(const Quaternion &q) const
Definition: CUQuaternion.h:776
Quaternion getNormalization() const
Definition: CUQuaternion.h:533
const Quaternion operator+(const Quaternion &q) const
Definition: CUQuaternion.h:656
Quaternion & operator-=(const Quaternion &q)
Definition: CUQuaternion.h:593
const Quaternion operator-(const Quaternion &q) const
Definition: CUQuaternion.h:670
static const Quaternion ZERO
Definition: CUQuaternion.h:111
Quaternion & setIdentity()
Definition: CUQuaternion.h:250
Quaternion getInverse() const
Definition: CUQuaternion.h:506
bool isUnit(float variance=CU_MATH_EPSILON) const
Definition: CUQuaternion.h:878
Quaternion & conjugate()
Definition: CUQuaternion.h:461
static Quaternion * slerp(const Quaternion &q1, const Quaternion &q2, float t, Quaternion *dst)
static Quaternion * multiply(const Quaternion &q1, const Quaternion &q2, Quaternion *dst)
Quaternion(float x, float y, float z, float w)
Definition: CUQuaternion.h:132
Quaternion & operator/=(float s)
Definition: CUQuaternion.h:628
int operator*(Font::Style value)
Definition: CUFont.h:1503
Quaternion & setZero()
Definition: CUQuaternion.h:260
float toAxisAngle(Vec3 *e) const
static Quaternion * scale(const Quaternion &q1, float s, Quaternion *dst)
Definition: CUVec3.h:61
Quaternion getLerp(const Quaternion &q, float t)
Definition: CUQuaternion.h:1053
Quaternion getNlerp(const Quaternion &q, float t)
Definition: CUQuaternion.h:1103
const Quaternion operator/(float s) const
Definition: CUQuaternion.h:726
Vec3 getRotation(const Vec3 &v)
Definition: CUQuaternion.h:1116
Quaternion & invert()
Definition: CUQuaternion.h:489
float z
Definition: CUQuaternion.h:106
Quaternion & nlerp(const Quaternion &q, float t)
Definition: CUQuaternion.h:1033
static Quaternion * divide(const Quaternion &q1, const Quaternion &q2, Quaternion *dst)
Definition: CUAction.h:51
Definition: CUQuaternion.h:97
Definition: CUMat4.h:92
Quaternion & add(const Quaternion &q)
Definition: CUQuaternion.h:401
Quaternion getSlerp(const Quaternion &q, float t)
Definition: CUQuaternion.h:1078
static Quaternion * createFromRotationMatrix(const Mat4 &m, Quaternion *dst)