Gamedev Framework (gf)  0.12.0
A C++14 framework for 2D games
Transform.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016-2019 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 
41  struct GF_API Rotation {
42  float cos;
43  float sin;
44 
51  : cos(1.0f), sin(0.0f)
52  {
53 
54  }
55 
61  Rotation(float angle)
62  : cos(std::cos(angle)), sin(std::sin(angle))
63  {
64 
65  }
66 
72  void setAngle(float angle) {
73  cos = std::cos(angle);
74  sin = std::sin(angle);
75  }
76 
82  float getAngle() const {
83  return std::atan2(sin, cos);
84  }
85  };
86 
95  constexpr
97  return {
98  rotation.cos * point.x - rotation.sin * point.y,
99  rotation.sin * point.x + rotation.cos * point.y
100  };
101  }
102 
111  constexpr
113  return {
114  rotation.cos * point.x + rotation.sin * point.y,
115  -rotation.sin * point.x + rotation.cos * point.y
116  };
117  }
118 
124  struct GF_API Translation {
126 
133  : offset(0.0f, 0.0f)
134  {
135 
136  }
137 
143  Translation(Vector2f translationOffset)
144  : offset(translationOffset)
145  {
146 
147  }
148 
154  void setOffset(Vector2f newOffset) noexcept {
155  offset = newOffset;
156  }
157 
163  Vector2f getOffset() const noexcept {
164  return offset;
165  }
166  };
167 
176  constexpr
178  return { point.x + translation.offset.x, point.y + translation.offset.y };
179  }
180 
189  constexpr
191  return { point.x - translation.offset.x, point.y - translation.offset.y };
192  }
193 
204  struct GF_API Transform {
207 
214  {
215 
216  }
217 
224  Transform(float angle, Vector2f offset)
225  : rotation(angle), translation(offset)
226  {
227 
228  }
229 
238  : rotation(angle)
239  {
240 
241  }
242 
251  : translation(offset)
252  {
253 
254  }
255 
261  void setAngle(float angle) {
262  rotation.setAngle(angle);
263  }
264 
270  float getAngle() const {
271  return rotation.getAngle();
272  }
273 
279  void setOffset(Vector2f offset) noexcept {
280  translation.setOffset(offset);
281  }
282 
288  Vector2f getOffset() const noexcept {
289  return translation.getOffset();
290  }
291 
292  };
293 
302  constexpr
303  Vector2f transform(const Transform& trans, Vector2f point) {
304  return transform(trans.translation, transform(trans.rotation, point));
305  }
306 
315  constexpr
317  return inverseTransform(trans.rotation, inverseTransform(trans.translation, point));
318  }
319 
320  // https://en.wikipedia.org/wiki/Homogeneous_coordinates
321 
330  constexpr
331  Vector2f transform(const Matrix3f& mat, Vector2f point) {
332  return { mat.xx * point.x + mat.xy * point.y + mat.xz, mat.yx * point.x + mat.yy * point.y + mat.yz };
333  }
334 
345  GF_API RectF transform(const Matrix3f& mat, const RectF& rect);
346 
347 
355  return Matrix3f(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
356  }
357 
365  inline
367  return Matrix3f{
368  1.0f, 0.0f, offset.x,
369  0.0f, 1.0f, offset.y,
370  0.0f, 0.0f, 1.0f
371  };
372  }
373 
381  GF_API void translate(Matrix3f& mat, Vector2f offset);
382 
390  inline
392  float cos = std::cos(angle);
393  float sin = std::sin(angle);
394  return Matrix3f{
395  cos, -sin, 0.0f,
396  sin, cos, 0.0f,
397  0.0f, 0.0f, 1.0f
398  };
399  }
400 
409  inline
410  Matrix3f rotation(float angle, Vector2f center) {
411  float cos = std::cos(angle);
412  float sin = std::sin(angle);
413  return Matrix3f{
414  cos, -sin, center.x * (1 - cos) + center.y * sin,
415  sin, cos, center.y * (1 - cos) - center.x * sin,
416  0.0f, 0.0f, 1.0f
417  };
418  }
419 
427  GF_API void rotate(Matrix3f& mat, float angle);
428 
437  GF_API void rotate(Matrix3f& mat, float angle, Vector2f center);
438 
446  inline
448  return Matrix3f{
449  factor.x, 0.0f, 0.0f,
450  0.0f, factor.y, 0.0f,
451  0.0f, 0.0f, 1.0f
452  };
453  }
454 
463  inline
464  Matrix3f scaling(Vector2f factor, Vector2f center) {
465  return Matrix3f{
466  factor.x, 0.0f, center.x * (1.0f - factor.x),
467  0.0f, factor.y, center.y * (1.0f - factor.y),
468  0.0f, 0.0f, 1.0f
469  };
470  }
471 
479  GF_API void scale(Matrix3f& mat, Vector2f factor);
480 
489  GF_API void scale(Matrix3f& mat, Vector2f factor, Vector2f center);
490 
491 #ifndef DOXYGEN_SHOULD_SKIP_THIS
492 }
493 #endif
494 }
495 
496 #endif // GF_TRANSFORM_H
constexpr Vector2f inverseTransform(const Translation &translation, Vector2f point)
Apply an inverse translation to a 2D point.
Definition: Transform.h:190
Vector2f getOffset() const noexcept
Get the translation offset.
Definition: Transform.h:288
Rotation(float angle)
Constructor with an angle.
Definition: Transform.h:61
constexpr Vector2f inverseTransform(const Transform &trans, Vector2f point)
Apply an inverse transformation to a 2D point.
Definition: Transform.h:316
void scale(Matrix3f &mat, Vector2f factor)
Combine the current transform with a scaling.
void setOffset(Vector2f newOffset) noexcept
Set the translation offset.
Definition: Transform.h:154
float getAngle() const
Get the rotation angle.
Definition: Transform.h:82
constexpr Vector2f transform(const Matrix3f &mat, Vector2f point)
Apply an affine transformation to a 2D point.
Definition: Transform.h:331
Vector2f offset
The offset of the translation.
Definition: Transform.h:125
Rotation rotation
The rotation of the transformation.
Definition: Transform.h:205
Transform(float angle)
Constructor with a rotation.
Definition: Transform.h:237
STL namespace.
Matrix3f scaling(Vector2f factor)
Get a scaling matrix.
Definition: Transform.h:447
void setOffset(Vector2f offset) noexcept
Set the translation offset.
Definition: Transform.h:279
A simple transformation (rotation then translation)
Definition: Transform.h:204
Matrix< float, 3, 3 > Matrix3f
A float square matrix of size 3.
Definition: Matrix.h:642
constexpr Vector2f transform(const Rotation &rotation, Vector2f point)
Apply a rotation to a 2D point.
Definition: Transform.h:96
float sin
The sine of the rotation angle.
Definition: Transform.h:43
A translation.
Definition: Transform.h:124
Translation translation
The translation of the transformation.
Definition: Transform.h:206
constexpr Vector2f transform(const Translation &translation, Vector2f point)
Apply a translation to a 2D point.
Definition: Transform.h:177
Translation()
Default constructor.
Definition: Transform.h:132
Vector2f getOffset() const noexcept
Get the translation offset.
Definition: Transform.h:163
Transform(float angle, Vector2f offset)
Constructor with a rotation and a translation.
Definition: Transform.h:224
General purpose math matrix.
Definition: Matrix.h:60
Translation(Vector2f translationOffset)
Constructor with an offset.
Definition: Transform.h:143
The namespace for gf classes.
Definition: Action.h:35
Matrix3f rotation(float angle)
Get a rotation matrix.
Definition: Transform.h:391
Transform(Vector2f offset)
Constructor with a translation.
Definition: Transform.h:250
float getAngle() const
Get the rotation angle.
Definition: Transform.h:270
float angle(Direction direction)
Get an angle from a direction.
void rotate(Matrix3f &mat, float angle)
Combine the current transform with a rotation.
Matrix3f translation(Vector2f offset)
Get a translation matrix.
Definition: Transform.h:366
void translate(Matrix3f &mat, Vector2f offset)
Combine the current transform with a translation.
Transform()
Default constructor.
Definition: Transform.h:213
constexpr Vector2f inverseTransform(const Rotation &rotation, Vector2f point)
Apply an inverse rotation to a 2D point.
Definition: Transform.h:112
void setAngle(float angle)
Set the rotation angle.
Definition: Transform.h:72
A rotation.
Definition: Transform.h:41
Rotation()
Default constructor.
Definition: Transform.h:50
constexpr Vector2f transform(const Transform &trans, Vector2f point)
Apply a transformation to a 2D point.
Definition: Transform.h:303
constexpr Matrix3f identityTransform()
Identity transform.
Definition: Transform.h:354
void setAngle(float angle)
Set the rotation angle.
Definition: Transform.h:261
float cos
The cosine of the rotation angle.
Definition: Transform.h:42