Gamedev Framework (gf)  0.1.0
A C++11 framework for 2D games
Transform.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016 Julien Bernard
4  *
5  * This software is provided 'as-is', without any express or implied
6  * warranty. In no event will the authors be held liable for any damages
7  * arising from the use of this software.
8  *
9  * Permission is granted to anyone to use this software for any purpose,
10  * including commercial applications, and to alter it and redistribute it
11  * freely, subject to the following restrictions:
12  *
13  * 1. The origin of this software must not be misrepresented; you must not
14  * claim that you wrote the original software. If you use this software
15  * in a product, an acknowledgment in the product documentation would be
16  * appreciated but is not required.
17  * 2. Altered source versions must be plainly marked as such, and must not be
18  * misrepresented as being the original software.
19  * 3. This notice may not be removed or altered from any source distribution.
20  */
21 #ifndef GF_TRANSFORM_H
22 #define GF_TRANSFORM_H
23 
24 #include <cmath>
25 
26 #include "Matrix.h"
27 #include "Portability.h"
28 #include "Rect.h"
29 #include "Vector.h"
30 
31 namespace gf {
32 #ifndef DOXYGEN_SHOULD_SKIP_THIS
33 inline namespace v1 {
34 #endif
35 
36  // https://en.wikipedia.org/wiki/Homogeneous_coordinates
37 
38  /**
39  * @ingroup core
40  * @brief Apply an affine transformation to a 2D point.
41  *
42  * @param mat The transformation matrix
43  * @param point The point to transform
44  * @return The transformed point
45  */
46  GF_API inline
47  Vector2f transform(const Matrix3f& mat, Vector2f point) {
48  Vector3f homogeneousPoint{point, 1.0f};
49  Vector3f result = mat * homogeneousPoint;
50  return result.xy;
51  }
52 
53  /**
54  * @ingroup core
55  * @brief Apply an affine transformaton to a rectangle
56  *
57  * The resulting rectangle is axis-aligned
58  *
59  * @param mat The transformation matrix
60  * @param rect The rectangle to transform
61  * @return The transformed rectangle
62  */
63  GF_API RectF transform(const Matrix3f& mat, const RectF& rect);
64 
65  /**
66  * @ingroup core
67  * @brief Get a translation matrix
68  *
69  * @param offset The offset of the translation
70  * @return A translation by `offset`
71  */
72  GF_API inline
74  return Matrix3f{
75  1.0f, 0.0f, offset.x,
76  0.0f, 1.0f, offset.y,
77  0.0f, 0.0f, 1.0f
78  };
79  }
80 
81  /**
82  * @ingroup core
83  * @brief Combine the current transform with a translation
84  *
85  * @param mat The current transform
86  * @param offset The offset of the translation
87  */
88  GF_API void translate(Matrix3f& mat, Vector2f offset);
89 
90  /**
91  * @ingroup core
92  * @brief Get a rotation matrix
93  *
94  * @param angle The angle of the rotation (in radians)
95  * @return A rotation of `angle` radians
96  */
97  GF_API inline
98  Matrix3f rotation(float angle) {
99  float cos = std::cos(angle);
100  float sin = std::sin(angle);
101  return Matrix3f{
102  cos, -sin, 0.0f,
103  sin, cos, 0.0f,
104  0.0f, 0.0f, 1.0f
105  };
106  }
107 
108  /**
109  * @ingroup core
110  * @brief Get a rotation matrix
111  *
112  * @param angle The angle of the rotation (in radians)
113  * @param center The center of the rotation
114  * @return A rotation of `angle` radians of origin `center`
115  */
116  GF_API inline
117  Matrix3f rotation(float angle, Vector2f center) {
118  float cos = std::cos(angle);
119  float sin = std::sin(angle);
120  return Matrix3f{
121  cos, -sin, center.x * (1 - cos) + center.x * sin,
122  sin, cos, center.y * (1 - cos) - center.y * sin,
123  0.0f, 0.0f, 1.0f
124  };
125  }
126 
127  /**
128  * @ingroup core
129  * @brief Combine the current transform with a rotation
130  *
131  * @param mat The current transform
132  * @param angle The angle of the rotation (in radians)
133  */
134  GF_API void rotate(Matrix3f& mat, float angle);
135 
136  /**
137  * @ingroup core
138  * @brief Combine the current transform with a rotation
139  *
140  * @param mat The current transform
141  * @param angle The angle of the rotation (in radians)
142  * @param center The center of the rotation
143  */
144  GF_API void rotate(Matrix3f& mat, float angle, Vector2f center);
145 
146  /**
147  * @ingroup core
148  * @brief Get a scaling matrix
149  *
150  * @param factor The scaling factor
151  * @return A scaling by `factor`
152  */
153  GF_API inline
155  return Matrix3f{
156  factor.x, 0.0f, 0.0f,
157  0.0f, factor.y, 0.0f,
158  0.0f, 0.0f, 1.0f
159  };
160  }
161 
162  /**
163  * @ingroup core
164  * @brief Get a scaling matrix
165  *
166  * @param factor The scaling factor
167  * @param center The center of the scaling
168  * @return A scaling by `factor` of origin `center`
169  */
170  GF_API inline
171  Matrix3f scaling(Vector2f factor, Vector2f center) {
172  return Matrix3f{
173  factor.x, 0.0f, center.x * (1.0f - factor.x),
174  0.0f, factor.y, center.y * (1.0f - factor.y),
175  0.0f, 0.0f, 1.0f
176  };
177  }
178 
179  /**
180  * @ingroup core
181  * @brief Combine the current transform with a scaling
182  *
183  * @param mat The current transform
184  * @param factor The scaling factor
185  */
186  GF_API void scale(Matrix3f& mat, Vector2f factor);
187 
188  /**
189  * @ingroup core
190  * @brief Combine the current transform with a scaling
191  *
192  * @param mat The current transform
193  * @param factor The scaling factor
194  * @param center The center of the scaling
195  */
196  GF_API void scale(Matrix3f& mat, Vector2f factor, Vector2f center);
197 
198 #ifndef DOXYGEN_SHOULD_SKIP_THIS
199 }
200 #endif
201 }
202 
203 #endif // GF_TRANSFORM_H
Vector2f transform(const Matrix3f &mat, Vector2f point)
Apply an affine transformation to a 2D point.
Definition: Transform.h:47
void scale(Matrix3f &mat, Vector2f factor)
Combine the current transform with a scaling.
Vector< float, 2 > Vector2f
A float vector with 2 components.
Definition: Vector.h:741
Matrix3f rotation(float angle, Vector2f center)
Get a rotation matrix.
Definition: Transform.h:117
Matrix3f scaling(Vector2f factor)
Get a scaling matrix.
Definition: Transform.h:154
Matrix< float, 3, 3 > Matrix3f
A float square matrix of size 3.
Definition: Matrix.h:326
Vector< T, S1 > operator*(const Matrix< T, S1, S2 > &lhs, const Vector< T, S2 > &rhs)
Matrix-vector multiplication.
Definition: Matrix.h:566
Matrix3f scaling(Vector2f factor, Vector2f center)
Get a scaling matrix.
Definition: Transform.h:171
void scale(Matrix3f &mat, Vector2f factor, Vector2f center)
Combine the current transform with a scaling.
Rect< float > RectF
A float rectangle.
Definition: Rect.h:306
Definition: Action.h:34
Matrix3f rotation(float angle)
Get a rotation matrix.
Definition: Transform.h:98
void rotate(Matrix3f &mat, float angle)
Combine the current transform with a rotation.
Matrix3f translation(Vector2f offset)
Get a translation matrix.
Definition: Transform.h:73
void translate(Matrix3f &mat, Vector2f offset)
Combine the current transform with a translation.
RectF transform(const Matrix3f &mat, const RectF &rect)
Apply an affine transformaton to a rectangle.
constexpr Matrix(T xx, T xy, T xz, T yx, T yy, T yz, T zx, T zy, T zz)
Constructor that takes all the elements.
Definition: Matrix.h:219
constexpr Vector(Vector< T, 2 > xy, T z)
Constructor that takes a 2D vector and a z component.
Definition: Vector.h:482
void rotate(Matrix3f &mat, float angle, Vector2f center)
Combine the current transform with a rotation.
#define GF_API
Definition: Portability.h:35
Vector< float, 3 > Vector3f
A float vector with 3 components.
Definition: Vector.h:747