0032137: Coding Rules - merge redundant .lxx files into header files within Package gp
[occt.git] / src / gp / gp_GTrsf2d.hxx
1 // Copyright (c) 1991-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #ifndef _gp_GTrsf2d_HeaderFile
16 #define _gp_GTrsf2d_HeaderFile
17
18 #include <gp_Ax2d.hxx>
19 #include <gp_Mat2d.hxx>
20 #include <gp_TrsfForm.hxx>
21 #include <gp_XY.hxx>
22 #include <Standard_ConstructionError.hxx>
23 #include <Standard_OutOfRange.hxx>
24
25 class gp_Trsf2d;
26 class gp_Mat2d;
27
28 //! Defines a non persistent transformation in 2D space.
29 //! This transformation is a general transformation.
30 //! It can be a gp_Trsf2d, an affinity, or you can
31 //! define your own transformation giving the corresponding matrix of transformation.
32 //!
33 //! With a gp_GTrsf2d you can transform only a doublet of coordinates gp_XY.
34 //! It is not possible to transform other geometric objects
35 //! because these transformations can change the nature of non-elementary geometric objects.
36 //! A gp_GTrsf2d is represented with a 2 rows * 3 columns matrix:
37 //! @code
38 //!    V1   V2   T        XY         XY
39 //! | a11  a12  a14 |   | x |      | x'|
40 //! | a21  a22  a24 |   | y |   =  | y'|
41 //! |  0    0    1  |   | 1 |      | 1 |
42 //! @endcode
43 //! where {V1, V2} defines the vectorial part of the
44 //! transformation and T defines the translation part of the transformation.
45 //! Warning
46 //! A gp_GTrsf2d transformation is only applicable on coordinates.
47 //! Be careful if you apply such a transformation to all the points of a geometric object,
48 //! as this can change the nature of the object and thus render it incoherent!
49 //! Typically, a circle is transformed into an ellipse by an affinity transformation.
50 //! To avoid modifying the nature of an object, use a gp_Trsf2d transformation instead,
51 //! as objects of this class respect the nature of geometric objects.
52 class gp_GTrsf2d 
53 {
54 public:
55
56   DEFINE_STANDARD_ALLOC
57
58   //! returns identity transformation.
59   gp_GTrsf2d()
60   {
61     shape = gp_Identity;
62     matrix.SetScale (1.0);
63     loc.SetCoord (0.0, 0.0);
64     scale = 1.0;
65   }
66
67   //! Converts the gp_Trsf2d transformation theT into a
68   //! general transformation.
69   gp_GTrsf2d (const gp_Trsf2d& theT);
70
71   //! Creates   a transformation based on the matrix theM and the
72   //! vector theV where theM defines the vectorial part of the
73   //! transformation, and theV the translation part.
74   gp_GTrsf2d (const gp_Mat2d& theM, const gp_XY& theV)
75   : matrix (theM),
76     loc (theV)
77   {
78     shape = gp_Other;
79     scale = 0.0;
80   }
81
82   //! Changes this transformation into an affinity of ratio theRatio
83   //! with respect to the axis theA.
84   //! Note: An affinity is a point-by-point transformation that
85   //! transforms any point P into a point P' such that if H is
86   //! the orthogonal projection of P on the axis theA, the vectors
87   //! HP and HP' satisfy: HP' = theRatio * HP.
88   Standard_EXPORT void SetAffinity (const gp_Ax2d& theA, const Standard_Real theRatio);
89
90   //! Replaces   the coefficient (theRow, theCol) of the matrix representing
91   //! this transformation by theValue,
92   //! Raises OutOfRange if theRow < 1 or theRow > 2 or theCol < 1 or theCol > 3
93   void SetValue (const Standard_Integer theRow, const Standard_Integer theCol, const Standard_Real theValue);
94
95   //! Replaces the translation part of this
96   //! transformation by the coordinates of the number pair theCoord.
97   Standard_EXPORT void SetTranslationPart (const gp_XY& theCoord);
98
99   //! Assigns the vectorial and translation parts of theT to this transformation.
100   void SetTrsf2d (const gp_Trsf2d& theT);
101
102   //! Replaces the vectorial part of this transformation by theMatrix.
103   void SetVectorialPart (const gp_Mat2d& theMatrix)
104   {
105     matrix = theMatrix;
106     shape = gp_Other;
107     scale = 0.0;
108   }
109
110   //! Returns true if the determinant of the vectorial part of
111   //! this transformation is negative.
112   Standard_Boolean IsNegative() const { return matrix.Determinant() < 0.0; }
113
114   //! Returns true if this transformation is singular (and
115   //! therefore, cannot be inverted).
116   //! Note: The Gauss LU decomposition is used to invert the
117   //! transformation matrix. Consequently, the transformation
118   //! is considered as singular if the largest pivot found is less
119   //! than or equal to gp::Resolution().
120   //! Warning
121   //! If this transformation is singular, it cannot be inverted.
122   Standard_Boolean IsSingular() const { return matrix.IsSingular(); }
123
124   //! Returns the nature of the transformation.  It can be
125   //! an identity transformation, a rotation, a translation, a mirror
126   //! transformation (relative to a point or axis), a scaling
127   //! transformation, a compound transformation or some
128   //! other type of transformation.
129   gp_TrsfForm Form() const { return shape; }
130
131   //! Returns the translation part of the GTrsf2d.
132   const gp_XY& TranslationPart() const { return loc; }
133
134   //! Computes the vectorial part of the GTrsf2d. The returned
135   //! Matrix is a 2*2 matrix.
136   const gp_Mat2d& VectorialPart() const { return matrix; }
137
138   //! Returns the coefficients of the global matrix of transformation.
139   //! Raised OutOfRange if theRow < 1 or theRow > 2 or theCol < 1 or theCol > 3
140   Standard_Real Value (const Standard_Integer theRow, const Standard_Integer theCol) const;
141
142   Standard_Real operator() (const Standard_Integer theRow, const Standard_Integer theCol) const { return Value (theRow, theCol); }
143
144   Standard_EXPORT void Invert();
145
146   //! Computes the reverse transformation.
147   //! Raised an exception if the matrix of the transformation
148   //! is not inversible.
149   Standard_NODISCARD gp_GTrsf2d Inverted() const
150   {
151     gp_GTrsf2d aT = *this;
152     aT.Invert();
153     return aT;
154   }
155
156   //! Computes the transformation composed with theT and <me>.
157   //! In a C++ implementation you can also write Tcomposed = <me> * theT.
158   //! Example :
159   //! @code
160   //! gp_GTrsf2d T1, T2, Tcomp; ...............
161   //! //composition :
162   //! Tcomp = T2.Multiplied(T1);         // or   (Tcomp = T2 * T1)
163   //! // transformation of a point
164   //! gp_XY P(10.,3.);
165   //! gp_XY P1(P);
166   //! Tcomp.Transforms(P1);               //using Tcomp
167   //! gp_XY P2(P);
168   //! T1.Transforms(P2);                  //using T1 then T2
169   //! T2.Transforms(P2);                  // P1 = P2 !!!
170   //! @endcode
171   Standard_NODISCARD gp_GTrsf2d Multiplied (const gp_GTrsf2d& theT) const
172   {
173     gp_GTrsf2d aTres = *this;
174     aTres.Multiply (theT);
175     return aTres;
176   }
177
178   Standard_NODISCARD gp_GTrsf2d operator * (const gp_GTrsf2d& theT) const { return Multiplied (theT); }
179
180   Standard_EXPORT void Multiply (const gp_GTrsf2d& theT);
181
182   void operator *= (const gp_GTrsf2d& theT) { Multiply (theT); }
183
184   //! Computes the product of the transformation theT and this
185   //! transformation, and assigns the result to this transformation:
186   //! this = theT * this
187   Standard_EXPORT void PreMultiply (const gp_GTrsf2d& theT);
188
189   Standard_EXPORT void Power (const Standard_Integer theN);
190
191   //! Computes the following composition of transformations
192   //! <me> * <me> * .......* <me>, theN time.
193   //! if theN = 0 <me> = Identity
194   //! if theN < 0 <me> = <me>.Inverse() *...........* <me>.Inverse().
195   //!
196   //! Raises an exception if theN < 0 and if the matrix of the
197   //! transformation is not inversible.
198   Standard_NODISCARD gp_GTrsf2d Powered (const Standard_Integer theN) const
199   {
200     gp_GTrsf2d aT = *this;
201     aT.Power (theN);
202     return aT;
203   }
204
205   void Transforms (gp_XY& theCoord) const;
206
207   Standard_NODISCARD gp_XY Transformed (const gp_XY& theCoord) const
208   {
209     gp_XY aNewCoord = theCoord;
210     Transforms (aNewCoord);
211     return aNewCoord;
212   }
213
214   //! Applies this transformation to the coordinates:
215   //! -   of the number pair Coord, or
216   //! -   X and Y.
217   //!
218   //! Note:
219   //! -   Transforms modifies theX, theY, or the coordinate pair Coord, while
220   //! -   Transformed creates a new coordinate pair.
221   void Transforms (Standard_Real& theX, Standard_Real& theY) const;
222
223   //! Converts this transformation into a gp_Trsf2d transformation.
224   //! Exceptions
225   //! Standard_ConstructionError if this transformation
226   //! cannot be converted, i.e. if its form is gp_Other.
227   Standard_EXPORT gp_Trsf2d Trsf2d() const;
228
229 private:
230
231   gp_Mat2d matrix;
232   gp_XY loc;
233   gp_TrsfForm shape;
234   Standard_Real scale;
235
236 };
237
238 #include <gp_Trsf2d.hxx>
239
240 //=======================================================================
241 //function : SetTrsf2d
242 // purpose :
243 //=======================================================================
244 inline void gp_GTrsf2d::SetTrsf2d (const gp_Trsf2d& theT)
245 {
246   shape = theT.shape;
247   matrix = theT.matrix;
248   loc = theT.loc;
249   scale = theT.scale;
250 }
251
252 //=======================================================================
253 //function : gp_GTrsf2d
254 // purpose :
255 //=======================================================================
256 inline gp_GTrsf2d::gp_GTrsf2d (const gp_Trsf2d& theT)
257 {
258   shape = theT.shape;
259   matrix = theT.matrix;
260   loc = theT.loc;
261   scale = theT.scale;
262 }
263
264 //=======================================================================
265 //function : SetValue
266 // purpose :
267 //=======================================================================
268 inline void gp_GTrsf2d::SetValue (const Standard_Integer theRow,
269                                   const Standard_Integer theCol,
270                                   const Standard_Real theValue)
271 {
272   Standard_OutOfRange_Raise_if
273     (theRow < 1 || theRow > 2 || theCol < 1 || theCol > 3, " ");
274   if (theCol == 3)
275   {
276     loc.SetCoord (theRow, theValue);
277   }
278   else
279   {
280     matrix.SetValue (theRow, theCol, theValue);
281   }
282   shape = gp_Other;
283 }
284
285 //=======================================================================
286 //function : Value
287 // purpose :
288 //=======================================================================
289 inline Standard_Real gp_GTrsf2d::Value (const Standard_Integer theRow,
290                                         const Standard_Integer theCol) const
291 {
292   Standard_OutOfRange_Raise_if
293     (theRow < 1 || theRow > 2 || theCol < 1 || theCol > 3, " ");
294   if (theCol == 3)
295   {
296     return loc.Coord (theRow);
297   }
298   if (shape == gp_Other)
299   {
300     return matrix.Value (theRow, theCol);
301   }
302   return scale * matrix.Value (theRow, theCol);
303 }
304
305 //=======================================================================
306 //function : Transforms
307 // purpose :
308 //=======================================================================
309 inline void gp_GTrsf2d::Transforms (gp_XY& theCoord) const
310 {
311   theCoord.Multiply (matrix);
312   if (!(shape == gp_Other) && !(scale == 1.0))
313   {
314     theCoord.Multiply (scale);
315   }
316   theCoord.Add (loc);
317 }
318
319 //=======================================================================
320 //function : Transforms
321 // purpose :
322 //=======================================================================
323 inline void gp_GTrsf2d::Transforms (Standard_Real& theX,
324                                     Standard_Real& theY) const
325 {
326   gp_XY aDoublet(theX, theY);
327   aDoublet.Multiply (matrix);
328   if (!(shape == gp_Other) && !(scale == 1.0))
329   {
330     aDoublet.Multiply (scale);
331   }
332   aDoublet.Add (loc);
333   aDoublet.Coord (theX, theY);
334 }
335
336 #endif // _gp_GTrsf2d_HeaderFile