CUGL
Cornell University Game Library
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends
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 
158  Quaternion(const Quaternion& copy) {
159  x = copy.x; y = copy.y; z = copy.z; w = copy.w;
160  }
161 
166 
167 
168 #pragma mark -
169 #pragma mark Static Constructors
170 
180  static Quaternion* createFromRotationMatrix(const Mat4& m, Quaternion* dst);
181 
193  static Quaternion* createFromAxisAngle(const Vec3& axis, float angle, Quaternion* dst);
194 
195 
196 #pragma mark -
197 #pragma mark Setters
198 
206  return set(v);
207  }
208 
218  Quaternion& operator=(const float* array) {
219  return set(array);
220  }
221 
232  Quaternion& set(float x, float y, float z, float w) {
233  this->x = x; this->y = y; this->z = z; this->w = w;
234  return *this;
235  }
236 
246  Quaternion& set(const float* array);
247 
256  Quaternion& set(const Vec3& axis, float angle);
257 
265  Quaternion& set(const Quaternion& q) {
266  x = q.x; y = q.y; z = q.z; w = q.w;
267  return *this;
268  }
269 
276  x = y = z = 0; w = 1;
277  return *this;
278  }
279 
286  x = y = z = w = 0;
287  return *this;
288  }
289 
290 
291 #pragma mark -
292 #pragma mark Static Arithmetic
293 
302  static Quaternion* add(const Quaternion& q1, const Quaternion& q2, Quaternion* dst);
303 
313  static Quaternion* subtract(const Quaternion& q1, const Quaternion& q2, Quaternion* dst);
314 
326  static Quaternion* multiply(const Quaternion& q1, const Quaternion& q2, Quaternion* dst);
327 
340  static Quaternion* divide(const Quaternion& q1, const Quaternion& q2, Quaternion* dst);
341 
351  static Quaternion* scale(const Quaternion& q1, float s, Quaternion* dst);
352 
361  static Quaternion* conjugate(const Quaternion& quat, Quaternion* dst);
362 
379  static Quaternion* invert(const Quaternion& quat, Quaternion* dst);
380 
392  static Quaternion* normalize(const Quaternion& quat, Quaternion* dst);
393 
402  static Quaternion* negate(const Quaternion& quat, Quaternion* dst);
403 
412  static float dot(const Quaternion& q1, const Quaternion& q2) {
413  return (q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w);
414  }
415 
416 
417 #pragma mark -
418 #pragma mark Arithmetic
419 
426  Quaternion& add(const Quaternion& q) {
427  x += q.x; y += q.y; z += q.z; w += q.w;
428  return *this;
429  }
430 
439  x -= q.x; y -= q.y; z -= q.z; w -= q.w;
440  return *this;
441  }
442 
451  return *(multiply(*this,q,this));
452  }
453 
454 
465  return *(divide(*this,q,this));
466  }
467 
468 
476  Quaternion& scale(float s) {
477  x *= s; y *= s; z *= s; w *= s;
478  return *this;
479  }
480 
487  x = -x; y = -y; z = -z;
488  return *this;
489  }
490 
497  Quaternion result;
498  return *(conjugate(*this,&result));
499  }
500 
515  return *(invert(*this,this));
516  }
517 
532  Quaternion result;
533  return *(invert(*this,&result));
534  }
535 
545  return *(normalize(*this,this));
546  }
547 
559  Quaternion result;
560  return *(normalize(*this,&result));
561  }
562 
569  x = -x; y = -y; z = -z; w = -w;
570  return *this;
571  }
572 
581  Quaternion result;
582  return *(negate(*this,&result));
583  }
584 
592  float dot(const Quaternion& q) const {
593  return (x * q.x + y * q.y + z * q.z + w * q.w);
594  }
595 
596 
597 
598 #pragma mark -
599 #pragma mark Operators
600 
608  return add(q);
609  }
610 
619  return subtract(q);
620  }
621 
629  Quaternion& operator*=(float s) {
630  return scale(s);
631  }
632 
643  return *(multiply(*this,q,this));
644  }
645 
653  Quaternion& operator/=(float s) {
654  return *(scale(*this,1.0f/s,this));
655  }
656 
669  return *(divide(*this,q,this));
670  }
671 
681  const Quaternion operator+(const Quaternion& q) const {
682  Quaternion result;
683  return *(add(*this,q,&result));
684  }
685 
695  const Quaternion operator-(const Quaternion& q) const {
696  Quaternion result;
697  return *(subtract(*this,q,&result));
698  }
699 
707  const Quaternion operator-() const {
708  Quaternion result;
709  return *(negate(*this,&result));
710  }
711 
721  const Quaternion operator*(float s) const {
722  Quaternion result;
723  return *(scale(*this,s,&result));
724  }
725 
737  const Quaternion operator*(const Quaternion& q) const {
738  Quaternion result;
739  return *(multiply(*this,q,&result));
740  }
741 
751  const Quaternion operator/(float s) const {
752  Quaternion result;
753  return *(scale(*this,1.0f/s,&result));
754  }
755 
769  const Quaternion operator/(const Quaternion& q) const {
770  Quaternion result;
771  return *(divide(*this,q,&result));
772  }
773 
774 
775 #pragma mark -
776 #pragma mark Comparisons
777 
787  bool operator==(const Quaternion& q) const {
788  return x == q.x && y == q.y && z == q.z && w == q.w;
789  }
790 
801  bool operator!=(const Quaternion& q) const {
802  return x != q.x || y != q.y || z != q.z || w != q.w;
803  }
804 
816  bool equals(const Quaternion& q, float variance=CU_MATH_EPSILON) const {
817  return (*this-q).normSquared() < variance*variance;
818  }
819 
820 #pragma mark -
821 #pragma mark Linear Attributes
822 
829  float norm() const {
830  return sqrt(normSquared());
831  }
832 
845  float normSquared() const {
846  return x*x+y*y+z*z+w*w;
847  }
848 
857  bool isZero() const {
858  return x == 0.0f && y == 0.0f && z == 0.0f && w == 0.0f;
859  }
860 
870  bool isNearZero(float variance=CU_MATH_EPSILON) const {
871  return normSquared() < variance*variance;
872  }
873 
879  bool isIdentity() const {
880  return x == 0.0f && y == 0.0f && z == 0.0f && w == 1.0f;
881  }
882 
892  bool isNearIdentity(float variance=CU_MATH_EPSILON) const {
893  return equals(IDENTITY,variance);
894  }
895 
903  bool isUnit(float variance=CU_MATH_EPSILON) const {
904  float dot = norm()-1.0f;
905  return fabsf(dot) <= variance;
906  }
907 
917  float toAxisAngle(Vec3* e) const;
918 
919 
920 #pragma mark -
921 #pragma mark Static Interpolation
922 
938  static Quaternion* lerp(const Quaternion& q1, const Quaternion& q2, float t, Quaternion* dst);
939 
960  static Quaternion* slerp(const Quaternion& q1, const Quaternion& q2, float t, Quaternion* dst);
961 
982  static Quaternion* nlerp(const Quaternion& q1, const Quaternion& q2, float t, Quaternion* dst);
983 
995  static Vec3* rotate(const Vec3& v, const Quaternion& quat, Vec3* dst);
996 
997 
998 #pragma mark -
999 #pragma mark Interpolation
1000 
1014  Quaternion& lerp(const Quaternion& q, float t) {
1015  return *(lerp(*this,q,t,this));
1016  }
1017 
1036  Quaternion& slerp(const Quaternion& q, float t) {
1037  return *(slerp(*this,q,t,this));
1038  }
1039 
1058  Quaternion& nlerp(const Quaternion& q, float t) {
1059  return *(slerp(*this,q,t,this));
1060  }
1061 
1078  Quaternion getLerp(const Quaternion& q, float t) {
1079  Quaternion result;
1080  return *(lerp(*this,q,t,&result));
1081  }
1082 
1103  Quaternion getSlerp(const Quaternion& q, float t) {
1104  Quaternion result;
1105  return *(slerp(*this,q,t,&result));
1106  }
1107 
1128  Quaternion getNlerp(const Quaternion& q, float t) {
1129  Quaternion result;
1130  return *(nlerp(*this,q,t,&result));
1131  }
1132 
1141  Vec3 getRotation(const Vec3& v) {
1142  Vec3 result;
1143  return *(rotate(v,*this,&result));
1144  }
1145 
1146 #pragma mark -
1147 #pragma mark Conversion Methods
1148 public:
1159  std::string toString(bool verbose = false) const;
1160 
1162  operator std::string() const { return toString(); }
1163 
1165  operator Vec4() const;
1166 
1172  explicit Quaternion(const Vec4& vector);
1173 
1181  Quaternion& operator= (const Vec4& vector) {
1182  return set(vector);
1183  }
1184 
1192  Quaternion& set(const Vec4& vector);
1193 
1200  operator Mat4() const;
1201 
1211  explicit Quaternion(const Mat4& m);
1212 
1225  return set(m);
1226  }
1227 
1239  Quaternion& set(const Mat4& m);
1240 
1241 };
1242 
1255 inline Vec3& operator*=(Vec3& v, const Quaternion& quat) {
1256  return *(Quaternion::rotate(v,quat,&v));
1257 }
1258 
1271 inline const Vec3 operator*(const Vec3& v, const Quaternion& quat) {
1272  Vec3 result;
1273  return *(Quaternion::rotate(v,quat,&result));
1274 }
1275 
1285 inline const Quaternion operator*(float s, const Quaternion& quat) {
1286  Quaternion result;
1287  return *(Quaternion::scale(quat,s,&result));
1288 }
1289 
1290 
1291 }
1292 
1293 #endif /* __CU_QUATERNION_H__ */
Quaternion & lerp(const Quaternion &q, float t)
Definition: CUQuaternion.h:1014
Quaternion(const Quaternion &copy)
Definition: CUQuaternion.h:158
std::string toString(bool verbose=false) const
bool operator==(const Quaternion &q) const
Definition: CUQuaternion.h:787
const Quaternion operator*(const Quaternion &q) const
Definition: CUQuaternion.h:737
Quaternion getNegation() const
Definition: CUQuaternion.h:580
const Quaternion operator-() const
Definition: CUQuaternion.h:707
Quaternion getConjugate() const
Definition: CUQuaternion.h:496
Vec2 & operator*=(Vec2 &v, const Affine2 &m)
Definition: CUAffine2.h:1145
Quaternion & multiply(const Quaternion &q)
Definition: CUQuaternion.h:450
static Quaternion * subtract(const Quaternion &q1, const Quaternion &q2, Quaternion *dst)
Quaternion & set(const Quaternion &q)
Definition: CUQuaternion.h:265
Quaternion & operator*=(float s)
Definition: CUQuaternion.h:629
static Quaternion * createFromAxisAngle(const Vec3 &axis, float angle, Quaternion *dst)
float normSquared() const
Definition: CUQuaternion.h:845
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:412
Quaternion()
Definition: CUQuaternion.h:122
bool equals(const Quaternion &q, float variance=CU_MATH_EPSILON) const
Definition: CUQuaternion.h:816
Quaternion & operator/=(const Quaternion &q)
Definition: CUQuaternion.h:668
float dot(const Quaternion &q) const
Definition: CUQuaternion.h:592
Quaternion & subtract(const Quaternion &q)
Definition: CUQuaternion.h:438
const Quaternion operator*(float s) const
Definition: CUQuaternion.h:721
Quaternion & operator*=(const Quaternion &q)
Definition: CUQuaternion.h:642
Quaternion & negate()
Definition: CUQuaternion.h:568
float norm() const
Definition: CUQuaternion.h:829
Quaternion & set(float x, float y, float z, float w)
Definition: CUQuaternion.h:232
static Quaternion * nlerp(const Quaternion &q1, const Quaternion &q2, float t, Quaternion *dst)
bool isIdentity() const
Definition: CUQuaternion.h:879
static Vec3 * rotate(const Vec3 &v, const Quaternion &quat, Vec3 *dst)
Quaternion & slerp(const Quaternion &q, float t)
Definition: CUQuaternion.h:1036
bool isNearIdentity(float variance=CU_MATH_EPSILON) const
Definition: CUQuaternion.h:892
Quaternion & operator+=(const Quaternion &q)
Definition: CUQuaternion.h:607
Quaternion & operator=(const float *array)
Definition: CUQuaternion.h:218
bool isNearZero(float variance=CU_MATH_EPSILON) const
Definition: CUQuaternion.h:870
bool isZero() const
Definition: CUQuaternion.h:857
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:769
Quaternion & scale(float s)
Definition: CUQuaternion.h:476
Quaternion & operator=(const Quaternion &v)
Definition: CUQuaternion.h:205
Quaternion & divide(const Quaternion &q)
Definition: CUQuaternion.h:464
float w
Definition: CUQuaternion.h:108
float y
Definition: CUQuaternion.h:104
Definition: CUVec4.h:73
Quaternion & normalize()
Definition: CUQuaternion.h:544
bool operator!=(const Quaternion &q) const
Definition: CUQuaternion.h:801
Quaternion getNormalization() const
Definition: CUQuaternion.h:558
const Quaternion operator+(const Quaternion &q) const
Definition: CUQuaternion.h:681
Quaternion & operator-=(const Quaternion &q)
Definition: CUQuaternion.h:618
const Quaternion operator-(const Quaternion &q) const
Definition: CUQuaternion.h:695
static const Quaternion ZERO
Definition: CUQuaternion.h:111
Quaternion & setIdentity()
Definition: CUQuaternion.h:275
Quaternion getInverse() const
Definition: CUQuaternion.h:531
bool isUnit(float variance=CU_MATH_EPSILON) const
Definition: CUQuaternion.h:903
~Quaternion()
Definition: CUQuaternion.h:165
Quaternion & conjugate()
Definition: CUQuaternion.h:486
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:653
int operator*(Font::Style value)
Definition: CUFont.h:1503
Quaternion & setZero()
Definition: CUQuaternion.h:285
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:1078
Quaternion getNlerp(const Quaternion &q, float t)
Definition: CUQuaternion.h:1128
const Quaternion operator/(float s) const
Definition: CUQuaternion.h:751
Vec3 getRotation(const Vec3 &v)
Definition: CUQuaternion.h:1141
Quaternion & invert()
Definition: CUQuaternion.h:514
float z
Definition: CUQuaternion.h:106
Quaternion & nlerp(const Quaternion &q, float t)
Definition: CUQuaternion.h:1058
static Quaternion * divide(const Quaternion &q1, const Quaternion &q2, Quaternion *dst)
Definition: CUAnimationNode.h:52
Definition: CUQuaternion.h:97
Definition: CUMat4.h:92
Quaternion & add(const Quaternion &q)
Definition: CUQuaternion.h:426
Quaternion getSlerp(const Quaternion &q, float t)
Definition: CUQuaternion.h:1103
static Quaternion * createFromRotationMatrix(const Mat4 &m, Quaternion *dst)