Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-02 08:58:14

0001 ////////////////////////////////////////////////////////////
0002 //
0003 // SFML - Simple and Fast Multimedia Library
0004 // Copyright (C) 2007-2023 Laurent Gomila (laurent@sfml-dev.org)
0005 //
0006 // This software is provided 'as-is', without any express or implied warranty.
0007 // In no event will the authors be held liable for any damages arising from the use of this software.
0008 //
0009 // Permission is granted to anyone to use this software for any purpose,
0010 // including commercial applications, and to alter it and redistribute it freely,
0011 // subject to the following restrictions:
0012 //
0013 // 1. The origin of this software must not be misrepresented;
0014 //    you must not claim that you wrote the original software.
0015 //    If you use this software in a product, an acknowledgment
0016 //    in the product documentation would be appreciated but is not required.
0017 //
0018 // 2. Altered source versions must be plainly marked as such,
0019 //    and must not be misrepresented as being the original software.
0020 //
0021 // 3. This notice may not be removed or altered from any source distribution.
0022 //
0023 ////////////////////////////////////////////////////////////
0024 
0025 #ifndef SFML_TRANSFORM_HPP
0026 #define SFML_TRANSFORM_HPP
0027 
0028 ////////////////////////////////////////////////////////////
0029 // Headers
0030 ////////////////////////////////////////////////////////////
0031 #include <SFML/Graphics/Export.hpp>
0032 #include <SFML/Graphics/Rect.hpp>
0033 #include <SFML/System/Vector2.hpp>
0034 
0035 
0036 namespace sf
0037 {
0038 ////////////////////////////////////////////////////////////
0039 /// \brief Define a 3x3 transform matrix
0040 ///
0041 ////////////////////////////////////////////////////////////
0042 class SFML_GRAPHICS_API Transform
0043 {
0044 public:
0045 
0046     ////////////////////////////////////////////////////////////
0047     /// \brief Default constructor
0048     ///
0049     /// Creates an identity transform (a transform that does nothing).
0050     ///
0051     ////////////////////////////////////////////////////////////
0052     Transform();
0053 
0054     ////////////////////////////////////////////////////////////
0055     /// \brief Construct a transform from a 3x3 matrix
0056     ///
0057     /// \param a00 Element (0, 0) of the matrix
0058     /// \param a01 Element (0, 1) of the matrix
0059     /// \param a02 Element (0, 2) of the matrix
0060     /// \param a10 Element (1, 0) of the matrix
0061     /// \param a11 Element (1, 1) of the matrix
0062     /// \param a12 Element (1, 2) of the matrix
0063     /// \param a20 Element (2, 0) of the matrix
0064     /// \param a21 Element (2, 1) of the matrix
0065     /// \param a22 Element (2, 2) of the matrix
0066     ///
0067     ////////////////////////////////////////////////////////////
0068     Transform(float a00, float a01, float a02,
0069               float a10, float a11, float a12,
0070               float a20, float a21, float a22);
0071 
0072     ////////////////////////////////////////////////////////////
0073     /// \brief Return the transform as a 4x4 matrix
0074     ///
0075     /// This function returns a pointer to an array of 16 floats
0076     /// containing the transform elements as a 4x4 matrix, which
0077     /// is directly compatible with OpenGL functions.
0078     ///
0079     /// \code
0080     /// sf::Transform transform = ...;
0081     /// glLoadMatrixf(transform.getMatrix());
0082     /// \endcode
0083     ///
0084     /// \return Pointer to a 4x4 matrix
0085     ///
0086     ////////////////////////////////////////////////////////////
0087     const float* getMatrix() const;
0088 
0089     ////////////////////////////////////////////////////////////
0090     /// \brief Return the inverse of the transform
0091     ///
0092     /// If the inverse cannot be computed, an identity transform
0093     /// is returned.
0094     ///
0095     /// \return A new transform which is the inverse of self
0096     ///
0097     ////////////////////////////////////////////////////////////
0098     Transform getInverse() const;
0099 
0100     ////////////////////////////////////////////////////////////
0101     /// \brief Transform a 2D point
0102     ///
0103     /// These two statements are equivalent:
0104     /// \code
0105     /// sf::Vector2f transformedPoint = matrix.transformPoint(x, y);
0106     /// sf::Vector2f transformedPoint = matrix * sf::Vector2f(x, y);
0107     /// \endcode
0108     ///
0109     /// \param x X coordinate of the point to transform
0110     /// \param y Y coordinate of the point to transform
0111     ///
0112     /// \return Transformed point
0113     ///
0114     ////////////////////////////////////////////////////////////
0115     Vector2f transformPoint(float x, float y) const;
0116 
0117     ////////////////////////////////////////////////////////////
0118     /// \brief Transform a 2D point
0119     ///
0120     /// These two statements are equivalent:
0121     /// \code
0122     /// sf::Vector2f transformedPoint = matrix.transformPoint(point);
0123     /// sf::Vector2f transformedPoint = matrix * point;
0124     /// \endcode
0125     ///
0126     /// \param point Point to transform
0127     ///
0128     /// \return Transformed point
0129     ///
0130     ////////////////////////////////////////////////////////////
0131     Vector2f transformPoint(const Vector2f& point) const;
0132 
0133     ////////////////////////////////////////////////////////////
0134     /// \brief Transform a rectangle
0135     ///
0136     /// Since SFML doesn't provide support for oriented rectangles,
0137     /// the result of this function is always an axis-aligned
0138     /// rectangle. Which means that if the transform contains a
0139     /// rotation, the bounding rectangle of the transformed rectangle
0140     /// is returned.
0141     ///
0142     /// \param rectangle Rectangle to transform
0143     ///
0144     /// \return Transformed rectangle
0145     ///
0146     ////////////////////////////////////////////////////////////
0147     FloatRect transformRect(const FloatRect& rectangle) const;
0148 
0149     ////////////////////////////////////////////////////////////
0150     /// \brief Combine the current transform with another one
0151     ///
0152     /// The result is a transform that is equivalent to applying
0153     /// \a transform followed by *this. Mathematically, it is
0154     /// equivalent to a matrix multiplication (*this) * transform.
0155     ///
0156     /// These two statements are equivalent:
0157     /// \code
0158     /// left.combine(right);
0159     /// left *= right;
0160     /// \endcode
0161     ///
0162     /// \param transform Transform to combine with this transform
0163     ///
0164     /// \return Reference to *this
0165     ///
0166     ////////////////////////////////////////////////////////////
0167     Transform& combine(const Transform& transform);
0168 
0169     ////////////////////////////////////////////////////////////
0170     /// \brief Combine the current transform with a translation
0171     ///
0172     /// This function returns a reference to *this, so that calls
0173     /// can be chained.
0174     /// \code
0175     /// sf::Transform transform;
0176     /// transform.translate(100, 200).rotate(45);
0177     /// \endcode
0178     ///
0179     /// \param x Offset to apply on X axis
0180     /// \param y Offset to apply on Y axis
0181     ///
0182     /// \return Reference to *this
0183     ///
0184     /// \see rotate, scale
0185     ///
0186     ////////////////////////////////////////////////////////////
0187     Transform& translate(float x, float y);
0188 
0189     ////////////////////////////////////////////////////////////
0190     /// \brief Combine the current transform with a translation
0191     ///
0192     /// This function returns a reference to *this, so that calls
0193     /// can be chained.
0194     /// \code
0195     /// sf::Transform transform;
0196     /// transform.translate(sf::Vector2f(100, 200)).rotate(45);
0197     /// \endcode
0198     ///
0199     /// \param offset Translation offset to apply
0200     ///
0201     /// \return Reference to *this
0202     ///
0203     /// \see rotate, scale
0204     ///
0205     ////////////////////////////////////////////////////////////
0206     Transform& translate(const Vector2f& offset);
0207 
0208     ////////////////////////////////////////////////////////////
0209     /// \brief Combine the current transform with a rotation
0210     ///
0211     /// This function returns a reference to *this, so that calls
0212     /// can be chained.
0213     /// \code
0214     /// sf::Transform transform;
0215     /// transform.rotate(90).translate(50, 20);
0216     /// \endcode
0217     ///
0218     /// \param angle Rotation angle, in degrees
0219     ///
0220     /// \return Reference to *this
0221     ///
0222     /// \see translate, scale
0223     ///
0224     ////////////////////////////////////////////////////////////
0225     Transform& rotate(float angle);
0226 
0227     ////////////////////////////////////////////////////////////
0228     /// \brief Combine the current transform with a rotation
0229     ///
0230     /// The center of rotation is provided for convenience as a second
0231     /// argument, so that you can build rotations around arbitrary points
0232     /// more easily (and efficiently) than the usual
0233     /// translate(-center).rotate(angle).translate(center).
0234     ///
0235     /// This function returns a reference to *this, so that calls
0236     /// can be chained.
0237     /// \code
0238     /// sf::Transform transform;
0239     /// transform.rotate(90, 8, 3).translate(50, 20);
0240     /// \endcode
0241     ///
0242     /// \param angle Rotation angle, in degrees
0243     /// \param centerX X coordinate of the center of rotation
0244     /// \param centerY Y coordinate of the center of rotation
0245     ///
0246     /// \return Reference to *this
0247     ///
0248     /// \see translate, scale
0249     ///
0250     ////////////////////////////////////////////////////////////
0251     Transform& rotate(float angle, float centerX, float centerY);
0252 
0253     ////////////////////////////////////////////////////////////
0254     /// \brief Combine the current transform with a rotation
0255     ///
0256     /// The center of rotation is provided for convenience as a second
0257     /// argument, so that you can build rotations around arbitrary points
0258     /// more easily (and efficiently) than the usual
0259     /// translate(-center).rotate(angle).translate(center).
0260     ///
0261     /// This function returns a reference to *this, so that calls
0262     /// can be chained.
0263     /// \code
0264     /// sf::Transform transform;
0265     /// transform.rotate(90, sf::Vector2f(8, 3)).translate(sf::Vector2f(50, 20));
0266     /// \endcode
0267     ///
0268     /// \param angle Rotation angle, in degrees
0269     /// \param center Center of rotation
0270     ///
0271     /// \return Reference to *this
0272     ///
0273     /// \see translate, scale
0274     ///
0275     ////////////////////////////////////////////////////////////
0276     Transform& rotate(float angle, const Vector2f& center);
0277 
0278     ////////////////////////////////////////////////////////////
0279     /// \brief Combine the current transform with a scaling
0280     ///
0281     /// This function returns a reference to *this, so that calls
0282     /// can be chained.
0283     /// \code
0284     /// sf::Transform transform;
0285     /// transform.scale(2, 1).rotate(45);
0286     /// \endcode
0287     ///
0288     /// \param scaleX Scaling factor on the X axis
0289     /// \param scaleY Scaling factor on the Y axis
0290     ///
0291     /// \return Reference to *this
0292     ///
0293     /// \see translate, rotate
0294     ///
0295     ////////////////////////////////////////////////////////////
0296     Transform& scale(float scaleX, float scaleY);
0297 
0298     ////////////////////////////////////////////////////////////
0299     /// \brief Combine the current transform with a scaling
0300     ///
0301     /// The center of scaling is provided for convenience as a second
0302     /// argument, so that you can build scaling around arbitrary points
0303     /// more easily (and efficiently) than the usual
0304     /// translate(-center).scale(factors).translate(center).
0305     ///
0306     /// This function returns a reference to *this, so that calls
0307     /// can be chained.
0308     /// \code
0309     /// sf::Transform transform;
0310     /// transform.scale(2, 1, 8, 3).rotate(45);
0311     /// \endcode
0312     ///
0313     /// \param scaleX Scaling factor on X axis
0314     /// \param scaleY Scaling factor on Y axis
0315     /// \param centerX X coordinate of the center of scaling
0316     /// \param centerY Y coordinate of the center of scaling
0317     ///
0318     /// \return Reference to *this
0319     ///
0320     /// \see translate, rotate
0321     ///
0322     ////////////////////////////////////////////////////////////
0323     Transform& scale(float scaleX, float scaleY, float centerX, float centerY);
0324 
0325     ////////////////////////////////////////////////////////////
0326     /// \brief Combine the current transform with a scaling
0327     ///
0328     /// This function returns a reference to *this, so that calls
0329     /// can be chained.
0330     /// \code
0331     /// sf::Transform transform;
0332     /// transform.scale(sf::Vector2f(2, 1)).rotate(45);
0333     /// \endcode
0334     ///
0335     /// \param factors Scaling factors
0336     ///
0337     /// \return Reference to *this
0338     ///
0339     /// \see translate, rotate
0340     ///
0341     ////////////////////////////////////////////////////////////
0342     Transform& scale(const Vector2f& factors);
0343 
0344     ////////////////////////////////////////////////////////////
0345     /// \brief Combine the current transform with a scaling
0346     ///
0347     /// The center of scaling is provided for convenience as a second
0348     /// argument, so that you can build scaling around arbitrary points
0349     /// more easily (and efficiently) than the usual
0350     /// translate(-center).scale(factors).translate(center).
0351     ///
0352     /// This function returns a reference to *this, so that calls
0353     /// can be chained.
0354     /// \code
0355     /// sf::Transform transform;
0356     /// transform.scale(sf::Vector2f(2, 1), sf::Vector2f(8, 3)).rotate(45);
0357     /// \endcode
0358     ///
0359     /// \param factors Scaling factors
0360     /// \param center Center of scaling
0361     ///
0362     /// \return Reference to *this
0363     ///
0364     /// \see translate, rotate
0365     ///
0366     ////////////////////////////////////////////////////////////
0367     Transform& scale(const Vector2f& factors, const Vector2f& center);
0368 
0369     ////////////////////////////////////////////////////////////
0370     // Static member data
0371     ////////////////////////////////////////////////////////////
0372     static const Transform Identity; //!< The identity transform (does nothing)
0373 
0374 private:
0375 
0376     ////////////////////////////////////////////////////////////
0377     // Member data
0378     ////////////////////////////////////////////////////////////
0379     float m_matrix[16]; //!< 4x4 matrix defining the transformation
0380 };
0381 
0382 ////////////////////////////////////////////////////////////
0383 /// \relates sf::Transform
0384 /// \brief Overload of binary operator * to combine two transforms
0385 ///
0386 /// This call is equivalent to calling Transform(left).combine(right).
0387 ///
0388 /// \param left Left operand (the first transform)
0389 /// \param right Right operand (the second transform)
0390 ///
0391 /// \return New combined transform
0392 ///
0393 ////////////////////////////////////////////////////////////
0394 SFML_GRAPHICS_API Transform operator *(const Transform& left, const Transform& right);
0395 
0396 ////////////////////////////////////////////////////////////
0397 /// \relates sf::Transform
0398 /// \brief Overload of binary operator *= to combine two transforms
0399 ///
0400 /// This call is equivalent to calling left.combine(right).
0401 ///
0402 /// \param left Left operand (the first transform)
0403 /// \param right Right operand (the second transform)
0404 ///
0405 /// \return The combined transform
0406 ///
0407 ////////////////////////////////////////////////////////////
0408 SFML_GRAPHICS_API Transform& operator *=(Transform& left, const Transform& right);
0409 
0410 ////////////////////////////////////////////////////////////
0411 /// \relates sf::Transform
0412 /// \brief Overload of binary operator * to transform a point
0413 ///
0414 /// This call is equivalent to calling left.transformPoint(right).
0415 ///
0416 /// \param left Left operand (the transform)
0417 /// \param right Right operand (the point to transform)
0418 ///
0419 /// \return New transformed point
0420 ///
0421 ////////////////////////////////////////////////////////////
0422 SFML_GRAPHICS_API Vector2f operator *(const Transform& left, const Vector2f& right);
0423 
0424 ////////////////////////////////////////////////////////////
0425 /// \relates sf::Transform
0426 /// \brief Overload of binary operator == to compare two transforms
0427 ///
0428 /// Performs an element-wise comparison of the elements of the
0429 /// left transform with the elements of the right transform.
0430 ///
0431 /// \param left Left operand (the first transform)
0432 /// \param right Right operand (the second transform)
0433 ///
0434 /// \return true if the transforms are equal, false otherwise
0435 ///
0436 ////////////////////////////////////////////////////////////
0437 SFML_GRAPHICS_API bool operator ==(const Transform& left, const Transform& right);
0438 
0439 ////////////////////////////////////////////////////////////
0440 /// \relates sf::Transform
0441 /// \brief Overload of binary operator != to compare two transforms
0442 ///
0443 /// This call is equivalent to !(left == right).
0444 ///
0445 /// \param left Left operand (the first transform)
0446 /// \param right Right operand (the second transform)
0447 ///
0448 /// \return true if the transforms are not equal, false otherwise
0449 ///
0450 ////////////////////////////////////////////////////////////
0451 SFML_GRAPHICS_API bool operator !=(const Transform& left, const Transform& right);
0452 
0453 } // namespace sf
0454 
0455 
0456 #endif // SFML_TRANSFORM_HPP
0457 
0458 
0459 ////////////////////////////////////////////////////////////
0460 /// \class sf::Transform
0461 /// \ingroup graphics
0462 ///
0463 /// A sf::Transform specifies how to translate, rotate, scale,
0464 /// shear, project, whatever things. In mathematical terms, it defines
0465 /// how to transform a coordinate system into another.
0466 ///
0467 /// For example, if you apply a rotation transform to a sprite, the
0468 /// result will be a rotated sprite. And anything that is transformed
0469 /// by this rotation transform will be rotated the same way, according
0470 /// to its initial position.
0471 ///
0472 /// Transforms are typically used for drawing. But they can also be
0473 /// used for any computation that requires to transform points between
0474 /// the local and global coordinate systems of an entity (like collision
0475 /// detection).
0476 ///
0477 /// Example:
0478 /// \code
0479 /// // define a translation transform
0480 /// sf::Transform translation;
0481 /// translation.translate(20, 50);
0482 ///
0483 /// // define a rotation transform
0484 /// sf::Transform rotation;
0485 /// rotation.rotate(45);
0486 ///
0487 /// // combine them
0488 /// sf::Transform transform = translation * rotation;
0489 ///
0490 /// // use the result to transform stuff...
0491 /// sf::Vector2f point = transform.transformPoint(10, 20);
0492 /// sf::FloatRect rect = transform.transformRect(sf::FloatRect(0, 0, 10, 100));
0493 /// \endcode
0494 ///
0495 /// \see sf::Transformable, sf::RenderStates
0496 ///
0497 ////////////////////////////////////////////////////////////