CUGL 1.2
Cornell University Game Library
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends
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 MIT 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 
127  Affine2(Affine2&& copy);
128 
132  ~Affine2() {}
133 
134 
135 #pragma mark -
136 #pragma mark Static Constructors
137 
144  static Affine2 createScale(float scale) {
145  Affine2 result;
146  return *(createScale(scale,&result));
147  }
148 
157  static Affine2* createScale(float scale, Affine2* dst);
158 
167  static Affine2 createScale(float sx, float sy) {
168  Affine2 result;
169  return *(createScale(sx,sy,&result));
170  }
171 
181  static Affine2* createScale(float sx, float sy, Affine2* dst);
182 
190  static Affine2 createScale(const Vec2& scale) {
191  Affine2 result;
192  return *(createScale(scale,&result));
193  }
194 
203  static Affine2* createScale(const Vec2& scale, Affine2* dst);
204 
215  static Affine2 createRotation(float angle) {
216  Affine2 result;
217  return *(createRotation(angle,&result));
218  }
219 
231  static Affine2* createRotation(float angle, Affine2* dst);
232 
240  static Affine2 createTranslation(const Vec2& trans) {
241  Affine2 result;
242  return *(createTranslation(trans,&result));
243  }
244 
253  static Affine2* createTranslation(const Vec2& trans, Affine2* dst);
254 
263  static Affine2 createTranslation(float tx, float ty) {
264  Affine2 result;
265  return *(createTranslation(tx,ty,&result));
266  }
267 
277  static Affine2* createTranslation(float tx, float ty, Affine2* dst);
278 
279 
280 #pragma mark -
281 #pragma mark Setters
282 
289  Affine2& operator=(const Affine2& mat) {
290  return set(mat);
291  }
292 
301  memcpy(this->m, mat.m, sizeof(float)*4);
302  this->offset = mat.offset;
303  return *this;
304  }
305 
320  Affine2& operator=(const float* array) {
321  return set(array);
322  }
323 
336  Affine2& set(float m11, float m12, float m21, float m22, float tx, float ty);
337 
352  Affine2& set(const float* mat);
353 
361  Affine2& set(const Affine2& mat);
362 
368  Affine2& setIdentity();
369 
375  Affine2& setZero();
376 
377 
378 #pragma mark -
379 #pragma mark Static Arithmetic
380 
391  static Affine2* add(const Affine2& m, const Vec2& v, Affine2* dst);
392 
404  static Affine2* subtract(const Affine2& m1, const Vec2& v, Affine2* dst);
405 
417  static Affine2* multiply(const Affine2& mat, float scalar, Affine2* dst);
418 
432  static Affine2* multiply(const Affine2& m1, const Affine2& m2, Affine2* dst);
433 
445  static Affine2* invert(const Affine2& m1, Affine2* dst);
446 
447 #pragma mark -
448 #pragma mark Arithmetic
449 
458  Affine2& add(const Vec2& v) {
459  return *(add(*this,v,this));
460  }
461 
471  Affine2& subtract(const Vec2& v) {
472  return *(subtract(*this,v,this));
473  }
474 
484  Affine2& multiply(float scalar) {
485  return *(multiply(*this,scalar,this));
486  }
487 
499  Affine2& multiply(const Affine2& aff) {
500  return *(multiply(*this,aff,this));
501  }
502 
512  return *(invert(*this,this));
513  }
514 
524  Affine2 getInverse() const {
525  Affine2 result;
526  invert(*this,&result);
527  return result;
528  }
529 
530 #pragma mark -
531 #pragma mark Operators
532 
541  Affine2& operator+=(const Vec2& v) {
542  return *(add(*this,v,this));
543  }
544 
554  Affine2& operator-=(const Vec2& v) {
555  return *(subtract(*this,v,this));
556  }
557 
567  Affine2& operator*=(float scalar) {
568  return *(multiply(*this,scalar,this));
569  }
570 
582  Affine2& operator*=(const Affine2& aff) {
583  return *(multiply(*this,aff,this));
584  }
585 
597  const Affine2 operator+(const Vec2& v) const {
598  Affine2 result;
599  return *(add(*this,v,&result));
600  }
601 
613  const Affine2 operator-(const Vec2& v) const {
614  Affine2 result;
615  return *(subtract(*this,v,&result));
616  }
617 
629  const Affine2 operator*(float scalar) const {
630  Affine2 result;
631  return *(multiply(*this,scalar,&result));
632  }
633 
634 
648  const Affine2 operator*(const Affine2& aff) const {
649  Affine2 result;
650  return *(multiply(*this,aff,&result));
651  }
652 
653 
654 #pragma mark -
655 #pragma mark Comparisons
656 
667  bool isExactly(const Affine2& aff) const;
668 
679  bool equals(const Affine2& mat, float variance=CU_MATH_EPSILON) const;
680 
692  bool operator==(const Affine2& aff) const {
693  return isExactly(aff);
694  }
695 
706  bool operator!=(const Affine2& aff) const {
707  return !isExactly(aff);
708  }
709 
710 #pragma mark -
711 #pragma mark Affine Attributes
712 
723  bool isIdentity(float variance=0.0f) const;
724 
734  bool isInvertible(float variance=CU_MATH_EPSILON) const {
735  return fabsf(getDeterminant()) > variance;
736  }
737 
746  float getDeterminant() const {
747  return m[0]*m[3]-m[2]*m[1];
748  }
749 
764  Vec2 getScale() const {
765  Vec2 result;
766  decompose(*this,&result,nullptr,nullptr);
767  return result;
768  }
769 
778  float getRotation() const {
779  float result;
780  decompose(*this,nullptr,&result,nullptr);
781  return result;
782  }
783 
794  Vec2 result;
795  decompose(*this,nullptr,nullptr,&result);
796  return result;
797  }
798 
799 #pragma mark -
800 #pragma mark Vector Operations
801 
810  static Vec2* transform(const Affine2& aff, const Vec2& point, Vec2* dst);
811 
824  static Rect* transform(const Affine2& aff, const Rect& rect, Rect* dst);
825 
836  Vec2 transform(const Vec2& point) const {
837  Vec2 result;
838  return *(transform(*this,point,&result));
839  }
840 
854  Rect transform(const Rect& rect) const;
855 
856 
857 #pragma mark -
858 #pragma mark Static Transform Manipulation
859 
873  static Affine2* rotate(const Affine2& aff, float angle, Affine2* dst) {
874  Affine2 result;
875  createRotation(angle, &result);
876  multiply(aff, result, dst);
877  return dst;
878  }
879 
892  static Affine2* scale(const Affine2& aff, float value, Affine2* dst) {
893  Affine2 result;
894  createScale(value, &result);
895  multiply(aff, result, dst);
896  return dst;
897  }
898 
911  static Affine2* scale(const Affine2& aff, const Vec2& s, Affine2* dst) {
912  Affine2 result;
913  createScale(s, &result);
914  multiply(aff, result, dst);
915  return dst;
916  }
917 
931  static Affine2* scale(const Affine2& aff, float sx, float sy, Affine2* dst) {
932  Affine2 result;
933  createScale(sx,sy, &result);
934  multiply(aff, result, dst);
935  return dst;
936  }
937 
950  static Affine2* translate(const Affine2& aff, const Vec2& t, Affine2* dst) {
951  Affine2 result;
952  createTranslation(t, &result);
953  multiply(aff, result, dst);
954  return dst;
955  }
956 
970  static Affine2* translate(const Affine2& aff, float tx, float ty, Affine2* dst) {
971  Affine2 result;
972  createTranslation(tx,ty, &result);
973  multiply(aff, result, dst);
974  return dst;
975  }
976 
1000  static bool decompose(const Affine2& mat, Vec2* scale, float* rot, Vec2* trans);
1001 
1002 
1003 #pragma mark -
1004 #pragma mark Matrix Transforms
1005 
1017  Affine2& rotate(float angle) {
1018  return *(rotate(*this,angle,this));
1019  }
1020 
1031  Affine2& scale(float value) {
1032  return *(scale(*this,value,this));
1033  }
1034 
1045  Affine2& scale(const Vec2& s) {
1046  return *(scale(*this,s,this));
1047  }
1048 
1060  Affine2& scale(float sx, float sy) {
1061  return *(scale(*this,sx,sy,this));
1062  }
1063 
1074  Affine2& translate(const Vec2& t) {
1075  return *(translate(*this,t,this));
1076  }
1077 
1089  Affine2& translate(float tx, float ty) {
1090  return *(translate(*this,tx,ty,this));
1091  }
1092 
1093 
1094 #pragma mark -
1095 #pragma mark Conversion Methods
1096 
1106  std::string toString(bool verbose = false) const;
1107 
1109  operator std::string() const { return toString(); }
1110 
1112  operator Mat4() const;
1113 
1123  explicit Affine2(const Mat4& mat);
1124 
1136  Affine2& operator= (const Mat4& mat);
1137 
1149  Affine2& set(const Mat4& mat);
1150 };
1151 
1152 #pragma mark -
1153 #pragma mark Vector Operations
1154 // To avoid confusion, we NEVER support vector on the right ops.
1155 
1165  inline Vec2& operator*=(Vec2& v, const Affine2& m) {
1166  return *(Affine2::transform(m,v,&v));
1167  }
1168 
1177 inline const Vec2 operator*(const Vec2& v, const Affine2& m) {
1178  Vec2 result;
1179  Affine2::transform(m,v,&result);
1180  return result;
1181 }
1182 
1193 inline const Affine2 operator*(float scalar, const Affine2& m) {
1194  Affine2 result(m);
1195  return result.multiply(scalar);
1196 }
1197 
1198 }
1199 #endif /* __CU_AFFINE2_H__ */
static Affine2 * multiply(const Affine2 &mat, float scalar, Affine2 *dst)
float getDeterminant() const
Definition: CUAffine2.h:746
Affine2 & subtract(const Vec2 &v)
Definition: CUAffine2.h:471
~Affine2()
Definition: CUAffine2.h:132
Affine2 & translate(float tx, float ty)
Definition: CUAffine2.h:1089
Definition: CUVec2.h:61
std::string toString(bool verbose=false) const
Vec2 transform(const Vec2 &point) const
Definition: CUAffine2.h:836
static Affine2 * translate(const Affine2 &aff, float tx, float ty, Affine2 *dst)
Definition: CUAffine2.h:970
Affine2 & rotate(float angle)
Definition: CUAffine2.h:1017
Affine2 & operator=(const float *array)
Definition: CUAffine2.h:320
Affine2 & scale(float sx, float sy)
Definition: CUAffine2.h:1060
Definition: CUAffine2.h:63
Affine2 & multiply(const Affine2 &aff)
Definition: CUAffine2.h:499
const Affine2 operator*(const Affine2 &aff) const
Definition: CUAffine2.h:648
bool operator==(const Affine2 &aff) const
Definition: CUAffine2.h:692
static const Affine2 ZERO
Definition: CUAffine2.h:72
static Affine2 * scale(const Affine2 &aff, float value, Affine2 *dst)
Definition: CUAffine2.h:892
const Affine2 operator+(const Vec2 &v) const
Definition: CUAffine2.h:597
Affine2 & translate(const Vec2 &t)
Definition: CUAffine2.h:1074
Affine2 & operator*=(const Affine2 &aff)
Definition: CUAffine2.h:582
bool isExactly(const Affine2 &aff) const
Affine2 getInverse() const
Definition: CUAffine2.h:524
static Affine2 createRotation(float angle)
Definition: CUAffine2.h:215
Affine2 & operator-=(const Vec2 &v)
Definition: CUAffine2.h:554
static Affine2 * translate(const Affine2 &aff, const Vec2 &t, Affine2 *dst)
Definition: CUAffine2.h:950
bool isInvertible(float variance=CU_MATH_EPSILON) const
Definition: CUAffine2.h:734
Affine2 & operator=(Affine2 &&mat)
Definition: CUAffine2.h:300
Affine2 & setIdentity()
static Affine2 createScale(float sx, float sy)
Definition: CUAffine2.h:167
static Affine2 * rotate(const Affine2 &aff, float angle, Affine2 *dst)
Definition: CUAffine2.h:873
const Affine2 operator*(float scalar) const
Definition: CUAffine2.h:629
static Vec2 * transform(const Affine2 &aff, const Vec2 &point, Vec2 *dst)
static Affine2 createTranslation(const Vec2 &trans)
Definition: CUAffine2.h:240
Affine2 & scale(const Vec2 &s)
Definition: CUAffine2.h:1045
bool equals(const Affine2 &mat, float variance=CU_MATH_EPSILON) const
float m[4]
Definition: CUAffine2.h:67
Affine2 & invert()
Definition: CUAffine2.h:511
Affine2 & operator+=(const Vec2 &v)
Definition: CUAffine2.h:541
Vec2 offset
Definition: CUAffine2.h:69
Definition: CURect.h:45
Affine2 & operator*=(float scalar)
Definition: CUAffine2.h:567
static const Affine2 IDENTITY
Definition: CUAffine2.h:76
Vec2 getScale() const
Definition: CUAffine2.h:764
Vec2 getTranslation() const
Definition: CUAffine2.h:793
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:911
Affine2 & add(const Vec2 &v)
Definition: CUAffine2.h:458
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:263
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:144
Affine2 & scale(float value)
Definition: CUAffine2.h:1031
static Affine2 * add(const Affine2 &m, const Vec2 &v, Affine2 *dst)
bool operator!=(const Affine2 &aff) const
Definition: CUAffine2.h:706
static Affine2 * scale(const Affine2 &aff, float sx, float sy, Affine2 *dst)
Definition: CUAffine2.h:931
Affine2 & operator=(const Affine2 &mat)
Definition: CUAffine2.h:289
Definition: CUAction.h:51
static Affine2 createScale(const Vec2 &scale)
Definition: CUAffine2.h:190
Definition: CUMat4.h:83
Affine2 & multiply(float scalar)
Definition: CUAffine2.h:484
bool isIdentity(float variance=0.0f) const
float getRotation() const
Definition: CUAffine2.h:778
const Affine2 operator-(const Vec2 &v) const
Definition: CUAffine2.h:613