Gamedev Framework (gf)  0.19.0
A C++17 framework for 2D games
Transform.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016-2021 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 "CoreApi.h"
27 #include "Matrix.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 
42  struct GF_CORE_API Rotation {
43  float cos;
44  float sin;
45 
52  : cos(1.0f), sin(0.0f)
53  {
54  }
55 
61  Rotation(float angle)
62  : cos(std::cos(angle)), sin(std::sin(angle))
63  {
64  }
65 
71  void setAngle(float angle) {
72  cos = std::cos(angle);
73  sin = std::sin(angle);
74  }
75 
81  float getAngle() const {
82  return std::atan2(sin, cos);
83  }
84  };
85 
94  constexpr
96  return {
97  rotation.cos * point.x - rotation.sin * point.y,
98  rotation.sin * point.x + rotation.cos * point.y
99  };
100  }
101 
110  constexpr
112  return {
113  rotation.cos * point.x + rotation.sin * point.y,
114  -rotation.sin * point.x + rotation.cos * point.y
115  };
116  }
117 
124  struct GF_CORE_API Translation {
126 
133  : offset(0.0f, 0.0f)
134  {
135  }
136 
142  Translation(Vector2f translationOffset)
143  : offset(translationOffset)
144  {
145  }
146 
152  void setOffset(Vector2f newOffset) noexcept {
153  offset = newOffset;
154  }
155 
161  Vector2f getOffset() const noexcept {
162  return offset;
163  }
164  };
165 
174  constexpr
176  return { point.x + translation.offset.x, point.y + translation.offset.y };
177  }
178 
187  constexpr
189  return { point.x - translation.offset.x, point.y - translation.offset.y };
190  }
191 
203  struct GF_CORE_API Transform {
206 
213  {
214  }
215 
222  Transform(float angle, Vector2f offset)
223  : rotation(angle), translation(offset)
224  {
225  }
226 
235  : rotation(angle)
236  {
237  }
238 
247  : translation(offset)
248  {
249  }
250 
256  void setAngle(float angle) {
257  rotation.setAngle(angle);
258  }
259 
265  float getAngle() const {
266  return rotation.getAngle();
267  }
268 
274  void setOffset(Vector2f offset) noexcept {
275  translation.setOffset(offset);
276  }
277 
283  Vector2f getOffset() const noexcept {
284  return translation.getOffset();
285  }
286 
287  };
288 
297  constexpr
298  Vector2f transform(const Transform& trans, Vector2f point) {
299  return transform(trans.translation, transform(trans.rotation, point));
300  }
301 
310  constexpr
312  return inverseTransform(trans.rotation, inverseTransform(trans.translation, point));
313  }
314 
315  // https://en.wikipedia.org/wiki/Homogeneous_coordinates
316 
325  constexpr
326  Vector2f transform(const Matrix3f& mat, Vector2f point) {
327  return { mat.xx * point.x + mat.xy * point.y + mat.xz, mat.yx * point.x + mat.yy * point.y + mat.yz };
328  }
329 
340  GF_CORE_API RectF transform(const Matrix3f& mat, const RectF& rect);
341 
342 
350  return Matrix3f(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
351  }
352 
360  inline
362  return Matrix3f{
363  1.0f, 0.0f, offset.x,
364  0.0f, 1.0f, offset.y,
365  0.0f, 0.0f, 1.0f
366  };
367  }
368 
376  GF_CORE_API void translate(Matrix3f& mat, Vector2f offset);
377 
385  inline
387  float cos = std::cos(angle);
388  float sin = std::sin(angle);
389  return Matrix3f{
390  cos, -sin, 0.0f,
391  sin, cos, 0.0f,
392  0.0f, 0.0f, 1.0f
393  };
394  }
395 
404  inline
405  Matrix3f rotation(float angle, Vector2f center) {
406  float cos = std::cos(angle);
407  float sin = std::sin(angle);
408  return Matrix3f{
409  cos, -sin, center.x * (1 - cos) + center.y * sin,
410  sin, cos, center.y * (1 - cos) - center.x * sin,
411  0.0f, 0.0f, 1.0f
412  };
413  }
414 
422  GF_CORE_API void rotate(Matrix3f& mat, float angle);
423 
432  GF_CORE_API void rotate(Matrix3f& mat, float angle, Vector2f center);
433 
441  inline
443  return Matrix3f{
444  factor.x, 0.0f, 0.0f,
445  0.0f, factor.y, 0.0f,
446  0.0f, 0.0f, 1.0f
447  };
448  }
449 
458  inline
459  Matrix3f scaling(Vector2f factor, Vector2f center) {
460  return Matrix3f{
461  factor.x, 0.0f, center.x * (1.0f - factor.x),
462  0.0f, factor.y, center.y * (1.0f - factor.y),
463  0.0f, 0.0f, 1.0f
464  };
465  }
466 
474  GF_CORE_API void scale(Matrix3f& mat, Vector2f factor);
475 
484  GF_CORE_API void scale(Matrix3f& mat, Vector2f factor, Vector2f center);
485 
486 #ifndef DOXYGEN_SHOULD_SKIP_THIS
487 }
488 #endif
489 }
490 
491 #endif // GF_TRANSFORM_H
constexpr Vector2f inverseTransform(const Translation &translation, Vector2f point)
Apply an inverse translation to a 2D point.
Definition: Transform.h:188
Vector2f getOffset() const noexcept
Get the translation offset.
Definition: Transform.h:283
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:311
void setOffset(Vector2f newOffset) noexcept
Set the translation offset.
Definition: Transform.h:152
GF_CORE_API void scale(Matrix3f &mat, Vector2f factor)
Combine the current transform with a scaling.
Matrix3f scaling(Vector2f factor)
Get a scaling matrix.
Definition: Transform.h:442
float getAngle() const
Get the rotation angle.
Definition: Transform.h:81
Vector2f offset
The offset of the translation.
Definition: Transform.h:125
Rotation rotation
The rotation of the transformation.
Definition: Transform.h:204
Transform(float angle)
Constructor with a rotation.
Definition: Transform.h:234
STL namespace.
void setOffset(Vector2f offset) noexcept
Set the translation offset.
Definition: Transform.h:274
A simple transformation (rotation then translation)
Definition: Transform.h:203
constexpr Vector2f transform(const Rotation &rotation, Vector2f point)
Apply a rotation to a 2D point.
Definition: Transform.h:95
float sin
The sine of the rotation angle.
Definition: Transform.h:44
A translation.
Definition: Transform.h:124
Translation translation
The translation of the transformation.
Definition: Transform.h:205
constexpr Vector2f transform(const Translation &translation, Vector2f point)
Apply a translation to a 2D point.
Definition: Transform.h:175
Translation()
Default constructor.
Definition: Transform.h:132
constexpr Matrix3f identityTransform()
Identity transform.
Definition: Transform.h:349
Vector2f getOffset() const noexcept
Get the translation offset.
Definition: Transform.h:161
Transform(float angle, Vector2f offset)
Constructor with a rotation and a translation.
Definition: Transform.h:222
Matrix3f rotation(float angle)
Get a rotation matrix.
Definition: Transform.h:386
constexpr Vector2f transform(const Matrix3f &mat, Vector2f point)
Apply an affine transformation to a 2D point.
Definition: Transform.h:326
Utility class for manipulating 2D axis aligned rectangles.
Definition: Rect.h:87
Translation(Vector2f translationOffset)
Constructor with an offset.
Definition: Transform.h:142
The namespace for gf classes.
Definition: Action.h:35
Transform(Vector2f offset)
Constructor with a translation.
Definition: Transform.h:246
float getAngle() const
Get the rotation angle.
Definition: Transform.h:265
Matrix< float, 3, 3 > Matrix3f
A float square matrix of size 3.
Definition: Matrix.h:630
Transform()
Default constructor.
Definition: Transform.h:212
constexpr Vector2f inverseTransform(const Rotation &rotation, Vector2f point)
Apply an inverse rotation to a 2D point.
Definition: Transform.h:111
void setAngle(float angle)
Set the rotation angle.
Definition: Transform.h:71
A rotation.
Definition: Transform.h:42
Rotation()
Default constructor.
Definition: Transform.h:51
GF_CORE_API float angle(Direction direction)
Get an angle from a direction.
constexpr Vector2f transform(const Transform &trans, Vector2f point)
Apply a transformation to a 2D point.
Definition: Transform.h:298
General purpose math vector.
Definition: Vector.h:61
GF_CORE_API void translate(Matrix3f &mat, Vector2f offset)
Combine the current transform with a translation.
Matrix3f translation(Vector2f offset)
Get a translation matrix.
Definition: Transform.h:361
GF_CORE_API void rotate(Matrix3f &mat, float angle)
Combine the current transform with a rotation.
void setAngle(float angle)
Set the rotation angle.
Definition: Transform.h:256
float cos
The cosine of the rotation angle.
Definition: Transform.h:43