Gamedev Framework (gf)  0.17.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 
60  Rotation(float angle)
61  : cos(std::cos(angle)), sin(std::sin(angle))
62  {
63  }
64 
70  void setAngle(float angle) {
71  cos = std::cos(angle);
72  sin = std::sin(angle);
73  }
74 
80  float getAngle() const {
81  return std::atan2(sin, cos);
82  }
83  };
84 
93  constexpr
95  return {
96  rotation.cos * point.x - rotation.sin * point.y,
97  rotation.sin * point.x + rotation.cos * point.y
98  };
99  }
100 
109  constexpr
111  return {
112  rotation.cos * point.x + rotation.sin * point.y,
113  -rotation.sin * point.x + rotation.cos * point.y
114  };
115  }
116 
122  struct GF_API Translation {
124 
131  : offset(0.0f, 0.0f)
132  {
133  }
134 
140  Translation(Vector2f translationOffset)
141  : offset(translationOffset)
142  {
143  }
144 
150  void setOffset(Vector2f newOffset) noexcept {
151  offset = newOffset;
152  }
153 
159  Vector2f getOffset() const noexcept {
160  return offset;
161  }
162  };
163 
172  constexpr
174  return { point.x + translation.offset.x, point.y + translation.offset.y };
175  }
176 
185  constexpr
187  return { point.x - translation.offset.x, point.y - translation.offset.y };
188  }
189 
200  struct GF_API Transform {
203 
210  {
211  }
212 
219  Transform(float angle, Vector2f offset)
220  : rotation(angle), translation(offset)
221  {
222  }
223 
232  : rotation(angle)
233  {
234  }
235 
244  : translation(offset)
245  {
246  }
247 
253  void setAngle(float angle) {
254  rotation.setAngle(angle);
255  }
256 
262  float getAngle() const {
263  return rotation.getAngle();
264  }
265 
271  void setOffset(Vector2f offset) noexcept {
272  translation.setOffset(offset);
273  }
274 
280  Vector2f getOffset() const noexcept {
281  return translation.getOffset();
282  }
283 
284  };
285 
294  constexpr
295  Vector2f transform(const Transform& trans, Vector2f point) {
296  return transform(trans.translation, transform(trans.rotation, point));
297  }
298 
307  constexpr
309  return inverseTransform(trans.rotation, inverseTransform(trans.translation, point));
310  }
311 
312  // https://en.wikipedia.org/wiki/Homogeneous_coordinates
313 
322  constexpr
323  Vector2f transform(const Matrix3f& mat, Vector2f point) {
324  return { mat.xx * point.x + mat.xy * point.y + mat.xz, mat.yx * point.x + mat.yy * point.y + mat.yz };
325  }
326 
337  GF_API RectF transform(const Matrix3f& mat, const RectF& rect);
338 
339 
347  return Matrix3f(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
348  }
349 
357  inline
359  return Matrix3f{
360  1.0f, 0.0f, offset.x,
361  0.0f, 1.0f, offset.y,
362  0.0f, 0.0f, 1.0f
363  };
364  }
365 
373  GF_API void translate(Matrix3f& mat, Vector2f offset);
374 
382  inline
384  float cos = std::cos(angle);
385  float sin = std::sin(angle);
386  return Matrix3f{
387  cos, -sin, 0.0f,
388  sin, cos, 0.0f,
389  0.0f, 0.0f, 1.0f
390  };
391  }
392 
401  inline
402  Matrix3f rotation(float angle, Vector2f center) {
403  float cos = std::cos(angle);
404  float sin = std::sin(angle);
405  return Matrix3f{
406  cos, -sin, center.x * (1 - cos) + center.y * sin,
407  sin, cos, center.y * (1 - cos) - center.x * sin,
408  0.0f, 0.0f, 1.0f
409  };
410  }
411 
419  GF_API void rotate(Matrix3f& mat, float angle);
420 
429  GF_API void rotate(Matrix3f& mat, float angle, Vector2f center);
430 
438  inline
440  return Matrix3f{
441  factor.x, 0.0f, 0.0f,
442  0.0f, factor.y, 0.0f,
443  0.0f, 0.0f, 1.0f
444  };
445  }
446 
455  inline
456  Matrix3f scaling(Vector2f factor, Vector2f center) {
457  return Matrix3f{
458  factor.x, 0.0f, center.x * (1.0f - factor.x),
459  0.0f, factor.y, center.y * (1.0f - factor.y),
460  0.0f, 0.0f, 1.0f
461  };
462  }
463 
471  GF_API void scale(Matrix3f& mat, Vector2f factor);
472 
481  GF_API void scale(Matrix3f& mat, Vector2f factor, Vector2f center);
482 
483 #ifndef DOXYGEN_SHOULD_SKIP_THIS
484 }
485 #endif
486 }
487 
488 #endif // GF_TRANSFORM_H
constexpr Vector2f inverseTransform(const Translation &translation, Vector2f point)
Apply an inverse translation to a 2D point.
Definition: Transform.h:186
Vector2f getOffset() const noexcept
Get the translation offset.
Definition: Transform.h:280
Rotation(float angle)
Constructor with an angle.
Definition: Transform.h:60
constexpr Vector2f inverseTransform(const Transform &trans, Vector2f point)
Apply an inverse transformation to a 2D point.
Definition: Transform.h:308
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:150
float getAngle() const
Get the rotation angle.
Definition: Transform.h:80
constexpr Vector2f transform(const Matrix3f &mat, Vector2f point)
Apply an affine transformation to a 2D point.
Definition: Transform.h:323
Vector2f offset
The offset of the translation.
Definition: Transform.h:123
Rotation rotation
The rotation of the transformation.
Definition: Transform.h:201
Transform(float angle)
Constructor with a rotation.
Definition: Transform.h:231
STL namespace.
Matrix3f scaling(Vector2f factor)
Get a scaling matrix.
Definition: Transform.h:439
void setOffset(Vector2f offset) noexcept
Set the translation offset.
Definition: Transform.h:271
A simple transformation (rotation then translation)
Definition: Transform.h:200
Matrix< float, 3, 3 > Matrix3f
A float square matrix of size 3.
Definition: Matrix.h:630
constexpr Vector2f transform(const Rotation &rotation, Vector2f point)
Apply a rotation to a 2D point.
Definition: Transform.h:94
float sin
The sine of the rotation angle.
Definition: Transform.h:43
A translation.
Definition: Transform.h:122
Translation translation
The translation of the transformation.
Definition: Transform.h:202
constexpr Vector2f transform(const Translation &translation, Vector2f point)
Apply a translation to a 2D point.
Definition: Transform.h:173
Translation()
Default constructor.
Definition: Transform.h:130
Vector2f getOffset() const noexcept
Get the translation offset.
Definition: Transform.h:159
Transform(float angle, Vector2f offset)
Constructor with a rotation and a translation.
Definition: Transform.h:219
Utility class for manipulating 2D axis aligned rectangles.
Definition: Rect.h:87
Translation(Vector2f translationOffset)
Constructor with an offset.
Definition: Transform.h:140
The namespace for gf classes.
Definition: Action.h:35
Matrix3f rotation(float angle)
Get a rotation matrix.
Definition: Transform.h:383
Transform(Vector2f offset)
Constructor with a translation.
Definition: Transform.h:243
float getAngle() const
Get the rotation angle.
Definition: Transform.h:262
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:358
void translate(Matrix3f &mat, Vector2f offset)
Combine the current transform with a translation.
Transform()
Default constructor.
Definition: Transform.h:209
constexpr Vector2f inverseTransform(const Rotation &rotation, Vector2f point)
Apply an inverse rotation to a 2D point.
Definition: Transform.h:110
void setAngle(float angle)
Set the rotation angle.
Definition: Transform.h:70
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:295
constexpr Matrix3f identityTransform()
Identity transform.
Definition: Transform.h:346
void setAngle(float angle)
Set the rotation angle.
Definition: Transform.h:253
float cos
The cosine of the rotation angle.
Definition: Transform.h:42