1 ////////////////////////////////////////////////////////////
3 // SFML - Simple and Fast Multimedia Library
4 // Copyright (C) 2007-2013 Laurent Gomila (laurent.gom@gmail.com)
6 // This software is provided 'as-is', without any express or implied warranty.
7 // In no event will the authors be held liable for any damages arising from the use of this software.
9 // Permission is granted to anyone to use this software for any purpose,
10 // including commercial applications, and to alter it and redistribute it freely,
11 // subject to the following restrictions:
13 // 1. The origin of this software must not be misrepresented;
14 // you must not claim that you wrote the original software.
15 // If you use this software in a product, an acknowledgment
16 // in the product documentation would be appreciated but is not required.
18 // 2. Altered source versions must be plainly marked as such,
19 // and must not be misrepresented as being the original software.
21 // 3. This notice may not be removed or altered from any source distribution.
23 ////////////////////////////////////////////////////////////
25 #ifndef SFML_TRANSFORM_HPP
26 #define SFML_TRANSFORM_HPP
28 ////////////////////////////////////////////////////////////
30 ////////////////////////////////////////////////////////////
31 #include <SFML/Graphics/Export.hpp>
32 #include <SFML/Graphics/Rect.hpp>
33 #include <SFML/System/Vector2.hpp>
38 ////////////////////////////////////////////////////////////
39 /// \brief Define a 3x3 transform matrix
41 ////////////////////////////////////////////////////////////
42 class SFML_GRAPHICS_API Transform
46 ////////////////////////////////////////////////////////////
47 /// \brief Default constructor
49 /// Creates an identity transform (a transform that does nothing).
51 ////////////////////////////////////////////////////////////
54 ////////////////////////////////////////////////////////////
55 /// \brief Construct a transform from a 3x3 matrix
57 /// \param a00 Element (0, 0) of the matrix
58 /// \param a01 Element (0, 1) of the matrix
59 /// \param a02 Element (0, 2) of the matrix
60 /// \param a10 Element (1, 0) of the matrix
61 /// \param a11 Element (1, 1) of the matrix
62 /// \param a12 Element (1, 2) of the matrix
63 /// \param a20 Element (2, 0) of the matrix
64 /// \param a21 Element (2, 1) of the matrix
65 /// \param a22 Element (2, 2) of the matrix
67 ////////////////////////////////////////////////////////////
68 Transform(float a00, float a01, float a02,
69 float a10, float a11, float a12,
70 float a20, float a21, float a22);
72 ////////////////////////////////////////////////////////////
73 /// \brief Return the transform as a 4x4 matrix
75 /// This function returns a pointer to an array of 16 floats
76 /// containing the transform elements as a 4x4 matrix, which
77 /// is directly compatible with OpenGL functions.
80 /// sf::Transform transform = ...;
81 /// glLoadMatrixf(transform.getMatrix());
84 /// \return Pointer to a 4x4 matrix
86 ////////////////////////////////////////////////////////////
87 const float* getMatrix() const;
89 ////////////////////////////////////////////////////////////
90 /// \brief Return the inverse of the transform
92 /// If the inverse cannot be computed, an identity transform
95 /// \return A new transform which is the inverse of self
97 ////////////////////////////////////////////////////////////
98 Transform getInverse() const;
100 ////////////////////////////////////////////////////////////
101 /// \brief Transform a 2D point
103 /// \param x X coordinate of the point to transform
104 /// \param y Y coordinate of the point to transform
106 /// \return Transformed point
108 ////////////////////////////////////////////////////////////
109 Vector2f transformPoint(float x, float y) const;
111 ////////////////////////////////////////////////////////////
112 /// \brief Transform a 2D point
114 /// \param point Point to transform
116 /// \return Transformed point
118 ////////////////////////////////////////////////////////////
119 Vector2f transformPoint(const Vector2f& point) const;
121 ////////////////////////////////////////////////////////////
122 /// \brief Transform a rectangle
124 /// Since SFML doesn't provide support for oriented rectangles,
125 /// the result of this function is always an axis-aligned
126 /// rectangle. Which means that if the transform contains a
127 /// rotation, the bounding rectangle of the transformed rectangle
130 /// \param rectangle Rectangle to transform
132 /// \return Transformed rectangle
134 ////////////////////////////////////////////////////////////
135 FloatRect transformRect(const FloatRect& rectangle) const;
137 ////////////////////////////////////////////////////////////
138 /// \brief Combine the current transform with another one
140 /// The result is a transform that is equivalent to applying
141 /// *this followed by \a transform. Mathematically, it is
142 /// equivalent to a matrix multiplication.
144 /// \param transform Transform to combine with this transform
146 /// \return Reference to *this
148 ////////////////////////////////////////////////////////////
149 Transform& combine(const Transform& transform);
151 ////////////////////////////////////////////////////////////
152 /// \brief Combine the current transform with a translation
154 /// This function returns a reference to *this, so that calls
157 /// sf::Transform transform;
158 /// transform.translate(100, 200).rotate(45);
161 /// \param x Offset to apply on X axis
162 /// \param y Offset to apply on Y axis
164 /// \return Reference to *this
166 /// \see rotate, scale
168 ////////////////////////////////////////////////////////////
169 Transform& translate(float x, float y);
171 ////////////////////////////////////////////////////////////
172 /// \brief Combine the current transform with a translation
174 /// This function returns a reference to *this, so that calls
177 /// sf::Transform transform;
178 /// transform.translate(sf::Vector2f(100, 200)).rotate(45);
181 /// \param offset Translation offset to apply
183 /// \return Reference to *this
185 /// \see rotate, scale
187 ////////////////////////////////////////////////////////////
188 Transform& translate(const Vector2f& offset);
190 ////////////////////////////////////////////////////////////
191 /// \brief Combine the current transform with a rotation
193 /// This function returns a reference to *this, so that calls
196 /// sf::Transform transform;
197 /// transform.rotate(90).translate(50, 20);
200 /// \param angle Rotation angle, in degrees
202 /// \return Reference to *this
204 /// \see translate, scale
206 ////////////////////////////////////////////////////////////
207 Transform& rotate(float angle);
209 ////////////////////////////////////////////////////////////
210 /// \brief Combine the current transform with a rotation
212 /// The center of rotation is provided for convenience as a second
213 /// argument, so that you can build rotations around arbitrary points
214 /// more easily (and efficiently) than the usual
215 /// translate(-center).rotate(angle).translate(center).
217 /// This function returns a reference to *this, so that calls
220 /// sf::Transform transform;
221 /// transform.rotate(90, 8, 3).translate(50, 20);
224 /// \param angle Rotation angle, in degrees
225 /// \param centerX X coordinate of the center of rotation
226 /// \param centerY Y coordinate of the center of rotation
228 /// \return Reference to *this
230 /// \see translate, scale
232 ////////////////////////////////////////////////////////////
233 Transform& rotate(float angle, float centerX, float centerY);
235 ////////////////////////////////////////////////////////////
236 /// \brief Combine the current transform with a rotation
238 /// The center of rotation is provided for convenience as a second
239 /// argument, so that you can build rotations around arbitrary points
240 /// more easily (and efficiently) than the usual
241 /// translate(-center).rotate(angle).translate(center).
243 /// This function returns a reference to *this, so that calls
246 /// sf::Transform transform;
247 /// transform.rotate(90, sf::Vector2f(8, 3)).translate(sf::Vector2f(50, 20));
250 /// \param angle Rotation angle, in degrees
251 /// \param center Center of rotation
253 /// \return Reference to *this
255 /// \see translate, scale
257 ////////////////////////////////////////////////////////////
258 Transform& rotate(float angle, const Vector2f& center);
260 ////////////////////////////////////////////////////////////
261 /// \brief Combine the current transform with a scaling
263 /// This function returns a reference to *this, so that calls
266 /// sf::Transform transform;
267 /// transform.scale(2, 1).rotate(45);
270 /// \param scaleX Scaling factor on the X axis
271 /// \param scaleY Scaling factor on the Y axis
273 /// \return Reference to *this
275 /// \see translate, rotate
277 ////////////////////////////////////////////////////////////
278 Transform& scale(float scaleX, float scaleY);
280 ////////////////////////////////////////////////////////////
281 /// \brief Combine the current transform with a scaling
283 /// The center of scaling is provided for convenience as a second
284 /// argument, so that you can build scaling around arbitrary points
285 /// more easily (and efficiently) than the usual
286 /// translate(-center).scale(factors).translate(center).
288 /// This function returns a reference to *this, so that calls
291 /// sf::Transform transform;
292 /// transform.scale(2, 1, 8, 3).rotate(45);
295 /// \param scaleX Scaling factor on X axis
296 /// \param scaleY Scaling factor on Y axis
297 /// \param centerX X coordinate of the center of scaling
298 /// \param centerY Y coordinate of the center of scaling
300 /// \return Reference to *this
302 /// \see translate, rotate
304 ////////////////////////////////////////////////////////////
305 Transform& scale(float scaleX, float scaleY, float centerX, float centerY);
307 ////////////////////////////////////////////////////////////
308 /// \brief Combine the current transform with a scaling
310 /// This function returns a reference to *this, so that calls
313 /// sf::Transform transform;
314 /// transform.scale(sf::Vector2f(2, 1)).rotate(45);
317 /// \param factors Scaling factors
319 /// \return Reference to *this
321 /// \see translate, rotate
323 ////////////////////////////////////////////////////////////
324 Transform& scale(const Vector2f& factors);
326 ////////////////////////////////////////////////////////////
327 /// \brief Combine the current transform with a scaling
329 /// The center of scaling is provided for convenience as a second
330 /// argument, so that you can build scaling around arbitrary points
331 /// more easily (and efficiently) than the usual
332 /// translate(-center).scale(factors).translate(center).
334 /// This function returns a reference to *this, so that calls
337 /// sf::Transform transform;
338 /// transform.scale(sf::Vector2f(2, 1), sf::Vector2f(8, 3)).rotate(45);
341 /// \param factors Scaling factors
342 /// \param center Center of scaling
344 /// \return Reference to *this
346 /// \see translate, rotate
348 ////////////////////////////////////////////////////////////
349 Transform& scale(const Vector2f& factors, const Vector2f& center);
351 ////////////////////////////////////////////////////////////
352 // Static member data
353 ////////////////////////////////////////////////////////////
354 static const Transform Identity; ///< The identity transform (does nothing)
358 ////////////////////////////////////////////////////////////
360 ////////////////////////////////////////////////////////////
361 float m_matrix[16]; ///< 4x4 matrix defining the transformation
364 ////////////////////////////////////////////////////////////
365 /// \relates sf::Transform
366 /// \brief Overload of binary operator * to combine two transforms
368 /// This call is equivalent to calling Transform(left).combine(right).
370 /// \param left Left operand (the first transform)
371 /// \param right Right operand (the second transform)
373 /// \return New combined transform
375 ////////////////////////////////////////////////////////////
376 SFML_GRAPHICS_API Transform operator *(const Transform& left, const Transform& right);
378 ////////////////////////////////////////////////////////////
379 /// \relates sf::Transform
380 /// \brief Overload of binary operator *= to combine two transforms
382 /// This call is equivalent to calling left.combine(right).
384 /// \param left Left operand (the first transform)
385 /// \param right Right operand (the second transform)
387 /// \return The combined transform
389 ////////////////////////////////////////////////////////////
390 SFML_GRAPHICS_API Transform& operator *=(Transform& left, const Transform& right);
392 ////////////////////////////////////////////////////////////
393 /// \relates sf::Transform
394 /// \brief Overload of binary operator * to transform a point
396 /// This call is equivalent to calling left.transformPoint(right).
398 /// \param left Left operand (the transform)
399 /// \param right Right operand (the point to transform)
401 /// \return New transformed point
403 ////////////////////////////////////////////////////////////
404 SFML_GRAPHICS_API Vector2f operator *(const Transform& left, const Vector2f& right);
409 #endif // SFML_TRANSFORM_HPP
412 ////////////////////////////////////////////////////////////
413 /// \class sf::Transform
414 /// \ingroup graphics
416 /// A sf::Transform specifies how to translate, rotate, scale,
417 /// shear, project, whatever things. In mathematical terms, it defines
418 /// how to transform a coordinate system into another.
420 /// For example, if you apply a rotation transform to a sprite, the
421 /// result will be a rotated sprite. And anything that is transformed
422 /// by this rotation transform will be rotated the same way, according
423 /// to its initial position.
425 /// Transforms are typically used for drawing. But they can also be
426 /// used for any computation that requires to transform points between
427 /// the local and global coordinate systems of an entity (like collision
432 /// // define a translation transform
433 /// sf::Transform translation;
434 /// translation.translate(20, 50);
436 /// // define a rotation transform
437 /// sf::Transform rotation;
438 /// rotation.rotate(45);
441 /// sf::Transform transform = translation * rotation;
443 /// // use the result to transform stuff...
444 /// sf::Vector2f point = transform.transformPoint(10, 20);
445 /// sf::FloatRect rect = transform.transformRect(sf::FloatRect(0, 0, 10, 100));
448 /// \see sf::Transformable, sf::RenderStates
450 ////////////////////////////////////////////////////////////