// Copyright (c) 1991-1999 Matra Datavision // Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #ifndef _gp_Trsf2d_HeaderFile #define _gp_Trsf2d_HeaderFile #include "gp_TrsfForm.hxx" #include "gp_Mat2d.hxx" #include "gp_XY.hxx" #include "Standard_OutOfRange.hxx" class gp_Trsf; class gp_Pnt2d; class gp_Ax2d; class gp_Vec2d; //! Defines a non-persistent transformation in 2D space. //! The following transformations are implemented : //! - Translation, Rotation, Scale //! - Symmetry with respect to a point and a line. //! Complex transformations can be obtained by combining the //! previous elementary transformations using the method Multiply. //! The transformations can be represented as follow : //! @code //! V1 V2 T XY XY //! | a11 a12 a13 | | x | | x'| //! | a21 a22 a23 | | y | | y'| //! | 0 0 1 | | 1 | | 1 | //! @endcode //! where {V1, V2} defines the vectorial part of the transformation //! and T defines the translation part of the transformation. //! This transformation never change the nature of the objects. class gp_Trsf2d { public: DEFINE_STANDARD_ALLOC //! Returns identity transformation. constexpr gp_Trsf2d() noexcept; //! Creates a 2d transformation in the XY plane from a //! 3d transformation . gp_Trsf2d(const gp_Trsf& theT); //! Changes the transformation into a symmetrical transformation. //! theP is the center of the symmetry. void SetMirror(const gp_Pnt2d& theP) noexcept; //! Changes the transformation into a symmetrical transformation. //! theA is the center of the axial symmetry. Standard_EXPORT void SetMirror(const gp_Ax2d& theA) noexcept; //! Changes the transformation into a rotation. //! theP is the rotation's center and theAng is the angular value of the //! rotation in radian. void SetRotation(const gp_Pnt2d& theP, const double theAng); //! Changes the transformation into a scale. //! theP is the center of the scale and theS is the scaling value. void SetScale(const gp_Pnt2d& theP, const double theS); //! Changes a transformation allowing passage from the coordinate //! system "theFromSystem1" to the coordinate system "theToSystem2". Standard_EXPORT void SetTransformation(const gp_Ax2d& theFromSystem1, const gp_Ax2d& theToSystem2); //! Changes the transformation allowing passage from the basic //! coordinate system //! {P(0.,0.,0.), VX (1.,0.,0.), VY (0.,1.,0.)} //! to the local coordinate system defined with the Ax2d theToSystem. Standard_EXPORT void SetTransformation(const gp_Ax2d& theToSystem); //! Changes the transformation into a translation. //! theV is the vector of the translation. void SetTranslation(const gp_Vec2d& theV); //! Makes the transformation into a translation from //! the point theP1 to the point theP2. void SetTranslation(const gp_Pnt2d& theP1, const gp_Pnt2d& theP2); //! Replaces the translation vector with theV. Standard_EXPORT void SetTranslationPart(const gp_Vec2d& theV); //! Modifies the scale factor. Standard_EXPORT void SetScaleFactor(const double theS); //! Returns true if the determinant of the vectorial part of //! this transformation is negative.. constexpr bool IsNegative() const noexcept { return (matrix.Determinant() < 0.0); } //! Returns the nature of the transformation. It can be an //! identity transformation, a rotation, a translation, a mirror //! (relative to a point or an axis), a scaling transformation, //! or a compound transformation. constexpr gp_TrsfForm Form() const noexcept { return shape; } //! Returns the scale factor. constexpr double ScaleFactor() const noexcept { return scale; } //! Returns the translation part of the transformation's matrix constexpr const gp_XY& TranslationPart() const noexcept { return loc; } //! Returns the vectorial part of the transformation. It is a //! 2*2 matrix which includes the scale factor. Standard_EXPORT gp_Mat2d VectorialPart() const; //! Returns the homogeneous vectorial part of the transformation. //! It is a 2*2 matrix which doesn't include the scale factor. //! The coefficients of this matrix must be multiplied by the //! scale factor to obtain the coefficients of the transformation. constexpr const gp_Mat2d& HVectorialPart() const noexcept { return matrix; } //! Returns the angle corresponding to the rotational component //! of the transformation matrix (operation opposite to SetRotation()). Standard_EXPORT double RotationPart() const; //! Returns the coefficients of the transformation's matrix. //! It is a 2 rows * 3 columns matrix. //! Raises OutOfRange if theRow < 1 or theRow > 2 or theCol < 1 or theCol > 3 constexpr double Value(const int theRow, const int theCol) const; Standard_EXPORT void Invert(); //! Computes the reverse transformation. //! Raises an exception if the matrix of the transformation //! is not inversible, it means that the scale factor is lower //! or equal to Resolution from package gp. [[nodiscard]] gp_Trsf2d Inverted() const { gp_Trsf2d aT = *this; aT.Invert(); return aT; } [[nodiscard]] gp_Trsf2d Multiplied(const gp_Trsf2d& theT) const { gp_Trsf2d aTresult(*this); aTresult.Multiply(theT); return aTresult; } [[nodiscard]] gp_Trsf2d operator*(const gp_Trsf2d& theT) const { return Multiplied(theT); } //! Computes the transformation composed from and theT. //! = * theT Standard_EXPORT void Multiply(const gp_Trsf2d& theT); void operator*=(const gp_Trsf2d& theT) { Multiply(theT); } //! Computes the transformation composed from and theT. //! = theT * Standard_EXPORT void PreMultiply(const gp_Trsf2d& theT); Standard_EXPORT void Power(const int theN); //! Computes the following composition of transformations //! * * .......* , theN time. //! if theN = 0 = Identity //! if theN < 0 = .Inverse() *...........* .Inverse(). //! //! Raises if theN < 0 and if the matrix of the transformation not //! inversible. gp_Trsf2d Powered(const int theN) { gp_Trsf2d aT = *this; aT.Power(theN); return aT; } constexpr void Transforms(double& theX, double& theY) const noexcept; //! Transforms a doublet XY with a Trsf2d constexpr void Transforms(gp_XY& theCoord) const noexcept; //! Sets the coefficients of the transformation. The //! transformation of the point x,y is the point //! x',y' with : //! @code //! x' = a11 x + a12 y + a13 //! y' = a21 x + a22 y + a23 //! @endcode //! The method Value(i,j) will return aij. //! Raises ConstructionError if the determinant of the aij is null. //! If the matrix as not a uniform scale it will be orthogonalized before future using. Standard_EXPORT void SetValues(const double a11, const double a12, const double a13, const double a21, const double a22, const double a23); friend class gp_GTrsf2d; protected: //! Makes orthogonalization of "matrix" Standard_EXPORT void Orthogonalize(); private: double scale; gp_TrsfForm shape; gp_Mat2d matrix; gp_XY loc; }; #include "gp_Trsf.hxx" #include "gp_Pnt2d.hxx" //================================================================================================= inline constexpr gp_Trsf2d::gp_Trsf2d() noexcept : scale(1.0), shape(gp_Identity), loc(0.0, 0.0) { matrix.SetIdentity(); } //================================================================================================= inline gp_Trsf2d::gp_Trsf2d(const gp_Trsf& theT) : scale(theT.ScaleFactor()), shape(theT.Form()), loc(theT.TranslationPart().X(), theT.TranslationPart().Y()) { const gp_Mat& M = theT.HVectorialPart(); matrix(1, 1) = M(1, 1); matrix(1, 2) = M(1, 2); matrix(2, 1) = M(2, 1); matrix(2, 2) = M(2, 2); } //================================================================================================= inline void gp_Trsf2d::SetRotation(const gp_Pnt2d& theP, const double theAng) { shape = gp_Rotation; scale = 1.0; loc = theP.XY(); loc.Reverse(); matrix.SetRotation(theAng); loc.Multiply(matrix); loc.Add(theP.XY()); } //================================================================================================= inline void gp_Trsf2d::SetMirror(const gp_Pnt2d& theP) noexcept { shape = gp_PntMirror; scale = -1.0; matrix.SetIdentity(); loc = theP.XY(); loc.Multiply(2.0); } //================================================================================================= inline void gp_Trsf2d::SetScale(const gp_Pnt2d& theP, const double theS) { shape = gp_Scale; scale = theS; matrix.SetIdentity(); loc = theP.XY(); loc.Multiply(1.0 - theS); } //================================================================================================= inline void gp_Trsf2d::SetTranslation(const gp_Vec2d& theV) { shape = gp_Translation; scale = 1.0; matrix.SetIdentity(); loc = theV.XY(); } //================================================================================================= inline void gp_Trsf2d::SetTranslation(const gp_Pnt2d& theP1, const gp_Pnt2d& theP2) { shape = gp_Translation; scale = 1.0; matrix.SetIdentity(); loc = (theP2.XY()).Subtracted(theP1.XY()); } //================================================================================================= inline constexpr double gp_Trsf2d::Value(const int theRow, const int theCol) const { Standard_OutOfRange_Raise_if(theRow < 1 || theRow > 2 || theCol < 1 || theCol > 3, " "); if (theCol < 3) { return scale * matrix.myMat[theRow - 1][theCol - 1]; } else { return loc.Coord(theRow); } } //================================================================================================= inline constexpr void gp_Trsf2d::Transforms(double& theX, double& theY) const noexcept { gp_XY aDoublet(theX, theY); aDoublet.Multiply(matrix); if (scale != 1.0) { aDoublet.Multiply(scale); } aDoublet.Add(loc); aDoublet.Coord(theX, theY); } //================================================================================================= inline constexpr void gp_Trsf2d::Transforms(gp_XY& theCoord) const noexcept { theCoord.Multiply(matrix); if (scale != 1.0) { theCoord.Multiply(scale); } theCoord.Add(loc); } #endif // _gp_Trsf2d_HeaderFile