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