CUGL
Cornell University Game Library
CUAffine2.h
1 //
2 // CUAffine2.h
3 // Cornell University Game Library (CUGL)
4 //
5 // This module provides support for a 2d affine transform. It has some of the
6 // functionality of Mat4, with a lot less memory footprint. Profiling suggests
7 // that this class is 20% faster than Mat4 when only 2d functionality is needed.
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/12/16
36 #ifndef __CU_AFFINE2_H__
37 #define __CU_AFFINE2_H__
38 
39 #include <math.h>
40 #include <assert.h>
41 #include "CUMathBase.h"
42 #include "CUVec2.h"
43 #include "CURect.h"
44 
45 namespace cugl {
46 
47 // Forward reference
48 class Mat4;
49 
63 class Affine2 {
64 #pragma mark Values
65 public:
67  float m[4];
70 
72  static const Affine2 ZERO;
74  static const Affine2 ONE;
76  static const Affine2 IDENTITY;
77 
78 #pragma mark -
79 #pragma mark Constructors
80 public:
87  Affine2();
88 
99  Affine2(float m11, float m12, float m21, float m22, float tx, float ty);
100 
113  Affine2(const float* mat);
114 
120  Affine2(const Affine2& copy);
121 
125  ~Affine2() {}
126 
127 
128 #pragma mark -
129 #pragma mark Static Constructors
130 
137  static Affine2 createScale(float scale) {
138  Affine2 result;
139  return *(createScale(scale,&result));
140  }
141 
150  static Affine2* createScale(float scale, Affine2* dst);
151 
160  static Affine2 createScale(float sx, float sy) {
161  Affine2 result;
162  return *(createScale(sx,sy,&result));
163  }
164 
174  static Affine2* createScale(float sx, float sy, Affine2* dst);
175 
183  static Affine2 createScale(const Vec2& scale) {
184  Affine2 result;
185  return *(createScale(scale,&result));
186  }
187 
196  static Affine2* createScale(const Vec2& scale, Affine2* dst);
197 
208  static Affine2 createRotation(float angle) {
209  Affine2 result;
210  return *(createRotation(angle,&result));
211  }
212 
224  static Affine2* createRotation(float angle, Affine2* dst);
225 
233  static Affine2 createTranslation(const Vec2& trans) {
234  Affine2 result;
235  return *(createTranslation(trans,&result));
236  }
237 
246  static Affine2* createTranslation(const Vec2& trans, Affine2* dst);
247 
256  static Affine2 createTranslation(float tx, float ty) {
257  Affine2 result;
258  return *(createTranslation(tx,ty,&result));
259  }
260 
270  static Affine2* createTranslation(float tx, float ty, Affine2* dst);
271 
272 
273 #pragma mark -
274 #pragma mark Setters
275 
282  Affine2& operator=(const Affine2& mat) {
283  return set(mat);
284  }
285 
300  Affine2& operator=(const float* array) {
301  return set(array);
302  }
303 
316  Affine2& set(float m11, float m12, float m21, float m22, float tx, float ty);
317 
332  Affine2& set(const float* mat);
333 
341  Affine2& set(const Affine2& mat);
342 
348  Affine2& setIdentity();
349 
355  Affine2& setZero();
356 
357 
358 #pragma mark -
359 #pragma mark Static Arithmetic
360 
371  static Affine2* add(const Affine2& m, const Vec2& v, Affine2* dst);
372 
384  static Affine2* subtract(const Affine2& m1, const Vec2& v, Affine2* dst);
385 
397  static Affine2* multiply(const Affine2& mat, float scalar, Affine2* dst);
398 
412  static Affine2* multiply(const Affine2& m1, const Affine2& m2, Affine2* dst);
413 
425  static Affine2* invert(const Affine2& m1, Affine2* dst);
426 
427 #pragma mark -
428 #pragma mark Arithmetic
429 
438  Affine2& add(const Vec2& v) {
439  return *(add(*this,v,this));
440  }
441 
451  Affine2& subtract(const Vec2& v) {
452  return *(subtract(*this,v,this));
453  }
454 
464  Affine2& multiply(float scalar) {
465  return *(multiply(*this,scalar,this));
466  }
467 
479  Affine2& multiply(const Affine2& aff) {
480  return *(multiply(*this,aff,this));
481  }
482 
492  return *(invert(*this,this));
493  }
494 
504  Affine2 getInverse() const {
505  Affine2 result;
506  invert(*this,&result);
507  return result;
508  }
509 
510 #pragma mark -
511 #pragma mark Operators
512 
521  Affine2& operator+=(const Vec2& v) {
522  return *(add(*this,v,this));
523  }
524 
534  Affine2& operator-=(const Vec2& v) {
535  return *(subtract(*this,v,this));
536  }
537 
547  Affine2& operator*=(float scalar) {
548  return *(multiply(*this,scalar,this));
549  }
550 
562  Affine2& operator*=(const Affine2& aff) {
563  return *(multiply(*this,aff,this));
564  }
565 
577  const Affine2 operator+(const Vec2& v) const {
578  Affine2 result;
579  return *(add(*this,v,&result));
580  }
581 
593  const Affine2 operator-(const Vec2& v) const {
594  Affine2 result;
595  return *(subtract(*this,v,&result));
596  }
597 
609  const Affine2 operator*(float scalar) const {
610  Affine2 result;
611  return *(multiply(*this,scalar,&result));
612  }
613 
614 
628  const Affine2 operator*(const Affine2& aff) const {
629  Affine2 result;
630  return *(multiply(*this,aff,&result));
631  }
632 
633 
634 #pragma mark -
635 #pragma mark Comparisons
636 
647  bool isExactly(const Affine2& aff) const;
648 
659  bool equals(const Affine2& mat, float variance=CU_MATH_EPSILON) const;
660 
672  bool operator==(const Affine2& aff) const {
673  return isExactly(aff);
674  }
675 
686  bool operator!=(const Affine2& aff) const {
687  return !isExactly(aff);
688  }
689 
690 #pragma mark -
691 #pragma mark Affine Attributes
692 
703  bool isIdentity(float variance=0.0f) const;
704 
714  bool isInvertible(float variance=CU_MATH_EPSILON) const {
715  return fabsf(getDeterminant()) > variance;
716  }
717 
726  float getDeterminant() const {
727  return m[0]*m[3]-m[2]*m[1];
728  }
729 
744  Vec2 getScale() const {
745  Vec2 result;
746  decompose(*this,&result,nullptr,nullptr);
747  return result;
748  }
749 
758  float getRotation() const {
759  float result;
760  decompose(*this,nullptr,&result,nullptr);
761  return result;
762  }
763 
774  Vec2 result;
775  decompose(*this,nullptr,nullptr,&result);
776  return result;
777  }
778 
779 #pragma mark -
780 #pragma mark Vector Operations
781 
790  static Vec2* transform(const Affine2& aff, const Vec2& point, Vec2* dst);
791 
804  static Rect* transform(const Affine2& aff, const Rect& rect, Rect* dst);
805 
816  Vec2 transform(const Vec2& point) const {
817  Vec2 result;
818  return *(transform(*this,point,&result));
819  }
820 
834  Rect transform(const Rect& rect) const;
835 
836 
837 #pragma mark -
838 #pragma mark Static Transform Manipulation
839 
853  static Affine2* rotate(const Affine2& aff, float angle, Affine2* dst) {
854  Affine2 result;
855  createRotation(angle, &result);
856  multiply(aff, result, dst);
857  return dst;
858  }
859 
872  static Affine2* scale(const Affine2& aff, float value, Affine2* dst) {
873  Affine2 result;
874  createScale(value, &result);
875  multiply(aff, result, dst);
876  return dst;
877  }
878 
891  static Affine2* scale(const Affine2& aff, const Vec2& s, Affine2* dst) {
892  Affine2 result;
893  createScale(s, &result);
894  multiply(aff, result, dst);
895  return dst;
896  }
897 
911  static Affine2* scale(const Affine2& aff, float sx, float sy, Affine2* dst) {
912  Affine2 result;
913  createScale(sx,sy, &result);
914  multiply(aff, result, dst);
915  return dst;
916  }
917 
930  static Affine2* translate(const Affine2& aff, const Vec2& t, Affine2* dst) {
931  Affine2 result;
932  createTranslation(t, &result);
933  multiply(aff, result, dst);
934  return dst;
935  }
936 
950  static Affine2* translate(const Affine2& aff, float tx, float ty, Affine2* dst) {
951  Affine2 result;
952  createTranslation(tx,ty, &result);
953  multiply(aff, result, dst);
954  return dst;
955  }
956 
980  static bool decompose(const Affine2& mat, Vec2* scale, float* rot, Vec2* trans);
981 
982 
983 #pragma mark -
984 #pragma mark Matrix Transforms
985 
997  Affine2& rotate(float angle) {
998  return *(rotate(*this,angle,this));
999  }
1000 
1011  Affine2& scale(float value) {
1012  return *(scale(*this,value,this));
1013  }
1014 
1025  Affine2& scale(const Vec2& s) {
1026  return *(scale(*this,s,this));
1027  }
1028 
1040  Affine2& scale(float sx, float sy) {
1041  return *(scale(*this,sx,sy,this));
1042  }
1043 
1054  Affine2& translate(const Vec2& t) {
1055  return *(translate(*this,t,this));
1056  }
1057 
1069  Affine2& translate(float tx, float ty) {
1070  return *(translate(*this,tx,ty,this));
1071  }
1072 
1073 
1074 #pragma mark -
1075 #pragma mark Conversion Methods
1076 
1086  std::string toString(bool verbose = false) const;
1087 
1089  operator std::string() const { return toString(); }
1090 
1092  operator Mat4() const;
1093 
1103  explicit Affine2(const Mat4& mat);
1104 
1116  Affine2& operator= (const Mat4& mat);
1117 
1129  Affine2& set(const Mat4& mat);
1130 };
1131 
1132 #pragma mark -
1133 #pragma mark Vector Operations
1134 // To avoid confusion, we NEVER support vector on the right ops.
1135 
1145  inline Vec2& operator*=(Vec2& v, const Affine2& m) {
1146  return *(Affine2::transform(m,v,&v));
1147  }
1148 
1157 inline const Vec2 operator*(const Vec2& v, const Affine2& m) {
1158  Vec2 result;
1159  Affine2::transform(m,v,&result);
1160  return result;
1161 }
1162 
1173 inline const Affine2 operator*(float scalar, const Affine2& m) {
1174  Affine2 result(m);
1175  return result.multiply(scalar);
1176 }
1177 
1178 }
1179 #endif /* __CU_AFFINE2_H__ */
static Affine2 * multiply(const Affine2 &mat, float scalar, Affine2 *dst)
float getDeterminant() const
Definition: CUAffine2.h:726
Affine2 & subtract(const Vec2 &v)
Definition: CUAffine2.h:451
~Affine2()
Definition: CUAffine2.h:125
Vec2 & operator*=(Vec2 &v, const Affine2 &m)
Definition: CUAffine2.h:1145
Affine2 & translate(float tx, float ty)
Definition: CUAffine2.h:1069
Definition: CUVec2.h:61
std::string toString(bool verbose=false) const
Vec2 transform(const Vec2 &point) const
Definition: CUAffine2.h:816
static Affine2 * translate(const Affine2 &aff, float tx, float ty, Affine2 *dst)
Definition: CUAffine2.h:950
Affine2 & rotate(float angle)
Definition: CUAffine2.h:997
Affine2 & operator=(const float *array)
Definition: CUAffine2.h:300
Affine2 & scale(float sx, float sy)
Definition: CUAffine2.h:1040
Definition: CUAffine2.h:63
Affine2 & multiply(const Affine2 &aff)
Definition: CUAffine2.h:479
const Affine2 operator*(const Affine2 &aff) const
Definition: CUAffine2.h:628
bool operator==(const Affine2 &aff) const
Definition: CUAffine2.h:672
static const Affine2 ZERO
Definition: CUAffine2.h:72
static Affine2 * scale(const Affine2 &aff, float value, Affine2 *dst)
Definition: CUAffine2.h:872
const Affine2 operator+(const Vec2 &v) const
Definition: CUAffine2.h:577
Affine2 & translate(const Vec2 &t)
Definition: CUAffine2.h:1054
Affine2 & operator*=(const Affine2 &aff)
Definition: CUAffine2.h:562
bool isExactly(const Affine2 &aff) const
Affine2 getInverse() const
Definition: CUAffine2.h:504
static Affine2 createRotation(float angle)
Definition: CUAffine2.h:208
Affine2 & operator-=(const Vec2 &v)
Definition: CUAffine2.h:534
static Affine2 * translate(const Affine2 &aff, const Vec2 &t, Affine2 *dst)
Definition: CUAffine2.h:930
bool isInvertible(float variance=CU_MATH_EPSILON) const
Definition: CUAffine2.h:714
Affine2 & setIdentity()
static Affine2 createScale(float sx, float sy)
Definition: CUAffine2.h:160
static Affine2 * rotate(const Affine2 &aff, float angle, Affine2 *dst)
Definition: CUAffine2.h:853
const Affine2 operator*(float scalar) const
Definition: CUAffine2.h:609
static Vec2 * transform(const Affine2 &aff, const Vec2 &point, Vec2 *dst)
static Affine2 createTranslation(const Vec2 &trans)
Definition: CUAffine2.h:233
Affine2 & scale(const Vec2 &s)
Definition: CUAffine2.h:1025
bool equals(const Affine2 &mat, float variance=CU_MATH_EPSILON) const
float m[4]
Definition: CUAffine2.h:67
Affine2 & invert()
Definition: CUAffine2.h:491
Affine2 & operator+=(const Vec2 &v)
Definition: CUAffine2.h:521
Vec2 offset
Definition: CUAffine2.h:69
Definition: CURect.h:45
Affine2 & operator*=(float scalar)
Definition: CUAffine2.h:547
static const Affine2 IDENTITY
Definition: CUAffine2.h:76
Vec2 getScale() const
Definition: CUAffine2.h:744
Vec2 getTranslation() const
Definition: CUAffine2.h:773
static bool decompose(const Affine2 &mat, Vec2 *scale, float *rot, Vec2 *trans)
static Affine2 * scale(const Affine2 &aff, const Vec2 &s, Affine2 *dst)
Definition: CUAffine2.h:891
Affine2 & add(const Vec2 &v)
Definition: CUAffine2.h:438
Affine2 & setZero()
Affine2 & set(float m11, float m12, float m21, float m22, float tx, float ty)
static Affine2 createTranslation(float tx, float ty)
Definition: CUAffine2.h:256
int operator*(Font::Style value)
Definition: CUFont.h:1503
static Affine2 * subtract(const Affine2 &m1, const Vec2 &v, Affine2 *dst)
static const Affine2 ONE
Definition: CUAffine2.h:74
static Affine2 createScale(float scale)
Definition: CUAffine2.h:137
Affine2 & scale(float value)
Definition: CUAffine2.h:1011
static Affine2 * add(const Affine2 &m, const Vec2 &v, Affine2 *dst)
bool operator!=(const Affine2 &aff) const
Definition: CUAffine2.h:686
static Affine2 * scale(const Affine2 &aff, float sx, float sy, Affine2 *dst)
Definition: CUAffine2.h:911
Affine2 & operator=(const Affine2 &mat)
Definition: CUAffine2.h:282
Definition: CUAnimationNode.h:52
static Affine2 createScale(const Vec2 &scale)
Definition: CUAffine2.h:183
Definition: CUMat4.h:92
Affine2 & multiply(float scalar)
Definition: CUAffine2.h:464
bool isIdentity(float variance=0.0f) const
float getRotation() const
Definition: CUAffine2.h:758
const Affine2 operator-(const Vec2 &v) const
Definition: CUAffine2.h:593