1 // Copyright (c) 1991-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #ifndef _gp_GTrsf_HeaderFile
16 #define _gp_GTrsf_HeaderFile
21 #include <gp_Trsf.hxx>
22 #include <gp_TrsfForm.hxx>
24 #include <Standard_ConstructionError.hxx>
25 #include <Standard_OutOfRange.hxx>
30 // Avoid possible conflict with SetForm macro defined by windows.h
35 //! Defines a non-persistent transformation in 3D space.
36 //! This transformation is a general transformation.
37 //! It can be a gp_Trsf, an affinity, or you can define
38 //! your own transformation giving the matrix of transformation.
40 //! With a gp_GTrsf you can transform only a triplet of coordinates gp_XYZ.
41 //! It is not possible to transform other geometric objects
42 //! because these transformations can change the nature of non-elementary geometric objects.
43 //! The transformation gp_GTrsf can be represented as follow:
45 //! V1 V2 V3 T XYZ XYZ
46 //! | a11 a12 a13 a14 | | x | | x'|
47 //! | a21 a22 a23 a24 | | y | | y'|
48 //! | a31 a32 a33 a34 | | z | = | z'|
49 //! | 0 0 0 1 | | 1 | | 1 |
51 //! where {V1, V2, V3} define the vectorial part of the
52 //! transformation and T defines the translation part of the transformation.
54 //! A gp_GTrsf transformation is only applicable to coordinates.
55 //! Be careful if you apply such a transformation to all points of a geometric object,
56 //! as this can change the nature of the object and thus render it incoherent!
57 //! Typically, a circle is transformed into an ellipse by an affinity transformation.
58 //! To avoid modifying the nature of an object, use a gp_Trsf transformation instead,
59 //! as objects of this class respect the nature of geometric objects.
66 //! Returns the Identity transformation.
70 matrix.SetScale (1.0);
71 loc.SetCoord (0.0, 0.0, 0.0);
75 //! Converts the gp_Trsf transformation theT into a
76 //! general transformation, i.e. Returns a GTrsf with
77 //! the same matrix of coefficients as the Trsf theT.
78 gp_GTrsf (const gp_Trsf& theT)
82 loc = theT.TranslationPart();
83 scale = theT.ScaleFactor();
86 //! Creates a transformation based on the matrix theM and the
87 //! vector theV where theM defines the vectorial part of
88 //! the transformation, and V the translation part, or
89 gp_GTrsf (const gp_Mat& theM, const gp_XYZ& theV)
97 //! Changes this transformation into an affinity of ratio theRatio
98 //! with respect to the axis theA1.
99 //! Note: an affinity is a point-by-point transformation that
100 //! transforms any point P into a point P' such that if H is
101 //! the orthogonal projection of P on the axis theA1 or the
102 //! plane A2, the vectors HP and HP' satisfy:
103 //! HP' = theRatio * HP.
104 void SetAffinity (const gp_Ax1& theA1, const Standard_Real theRatio);
106 //! Changes this transformation into an affinity of ratio theRatio
107 //! with respect to the plane defined by the origin, the "X Direction" and
108 //! the "Y Direction" of coordinate system theA2.
109 //! Note: an affinity is a point-by-point transformation that
110 //! transforms any point P into a point P' such that if H is
111 //! the orthogonal projection of P on the axis A1 or the
112 //! plane theA2, the vectors HP and HP' satisfy:
113 //! HP' = theRatio * HP.
114 void SetAffinity (const gp_Ax2& theA2, const Standard_Real theRatio);
116 //! Replaces the coefficient (theRow, theCol) of the matrix representing
117 //! this transformation by theValue. Raises OutOfRange
118 //! if theRow < 1 or theRow > 3 or theCol < 1 or theCol > 4
119 void SetValue (const Standard_Integer theRow, const Standard_Integer theCol, const Standard_Real theValue);
121 //! Replaces the vectorial part of this transformation by theMatrix.
122 void SetVectorialPart (const gp_Mat& theMatrix)
129 //! Replaces the translation part of
130 //! this transformation by the coordinates of the number triple theCoord.
131 Standard_EXPORT void SetTranslationPart (const gp_XYZ& theCoord);
133 //! Assigns the vectorial and translation parts of theT to this transformation.
134 void SetTrsf (const gp_Trsf& theT)
137 matrix = theT.matrix;
142 //! Returns true if the determinant of the vectorial part of
143 //! this transformation is negative.
144 Standard_Boolean IsNegative() const { return matrix.Determinant() < 0.0; }
146 //! Returns true if this transformation is singular (and
147 //! therefore, cannot be inverted).
148 //! Note: The Gauss LU decomposition is used to invert the
149 //! transformation matrix. Consequently, the transformation
150 //! is considered as singular if the largest pivot found is less
151 //! than or equal to gp::Resolution().
153 //! If this transformation is singular, it cannot be inverted.
154 Standard_Boolean IsSingular() const { return matrix.IsSingular(); }
156 //! Returns the nature of the transformation. It can be an
157 //! identity transformation, a rotation, a translation, a mirror
158 //! transformation (relative to a point, an axis or a plane), a
159 //! scaling transformation, a compound transformation or
160 //! some other type of transformation.
161 gp_TrsfForm Form() const { return shape; }
163 //! verify and set the shape of the GTrsf Other or CompoundTrsf
166 //! myGTrsf.SetValue(row1,col1,val1);
167 //! myGTrsf.SetValue(row2,col2,val2);
169 //! myGTrsf.SetForm();
171 Standard_EXPORT void SetForm();
173 //! Returns the translation part of the GTrsf.
174 const gp_XYZ& TranslationPart() const { return loc; }
176 //! Computes the vectorial part of the GTrsf. The returned Matrix
178 const gp_Mat& VectorialPart() const { return matrix; }
180 //! Returns the coefficients of the global matrix of transformation.
181 //! Raises OutOfRange if theRow < 1 or theRow > 3 or theCol < 1 or theCol > 4
182 Standard_Real Value (const Standard_Integer theRow, const Standard_Integer theCol) const;
184 Standard_Real operator() (const Standard_Integer theRow, const Standard_Integer theCol) const { return Value (theRow, theCol); }
186 Standard_EXPORT void Invert();
188 //! Computes the reverse transformation.
189 //! Raises an exception if the matrix of the transformation
190 //! is not inversible.
191 Standard_NODISCARD gp_GTrsf Inverted() const
198 //! Computes the transformation composed from theT and <me>.
199 //! In a C++ implementation you can also write Tcomposed = <me> * theT.
202 //! gp_GTrsf T1, T2, Tcomp; ...............
204 //! Tcomp = T2.Multiplied(T1); // or (Tcomp = T2 * T1)
205 //! // transformation of a point
206 //! gp_XYZ P(10.,3.,4.);
208 //! Tcomp.Transforms(P1); //using Tcomp
210 //! T1.Transforms(P2); //using T1 then T2
211 //! T2.Transforms(P2); // P1 = P2 !!!
213 Standard_NODISCARD gp_GTrsf Multiplied (const gp_GTrsf& theT) const
215 gp_GTrsf aTres = *this;
216 aTres.Multiply (theT);
220 Standard_NODISCARD gp_GTrsf operator * (const gp_GTrsf& theT) const { return Multiplied (theT); }
222 //! Computes the transformation composed with <me> and theT.
223 //! <me> = <me> * theT
224 Standard_EXPORT void Multiply (const gp_GTrsf& theT);
226 void operator *= (const gp_GTrsf& theT) { Multiply (theT); }
228 //! Computes the product of the transformation theT and this
229 //! transformation and assigns the result to this transformation.
230 //! this = theT * this
231 Standard_EXPORT void PreMultiply (const gp_GTrsf& theT);
233 Standard_EXPORT void Power (const Standard_Integer theN);
236 //! - the product of this transformation multiplied by itself
237 //! theN times, if theN is positive, or
238 //! - the product of the inverse of this transformation
239 //! multiplied by itself |theN| times, if theN is negative.
240 //! If theN equals zero, the result is equal to the Identity
242 //! I.e.: <me> * <me> * .......* <me>, theN time.
243 //! if theN =0 <me> = Identity
244 //! if theN < 0 <me> = <me>.Inverse() *...........* <me>.Inverse().
246 //! Raises an exception if N < 0 and if the matrix of the
247 //! transformation not inversible.
248 Standard_NODISCARD gp_GTrsf Powered (const Standard_Integer theN) const
255 void Transforms (gp_XYZ& theCoord) const;
257 //! Transforms a triplet XYZ with a GTrsf.
258 void Transforms (Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ) const;
260 gp_Trsf Trsf() const;
262 //! Convert transformation to 4x4 matrix.
264 void GetMat4 (NCollection_Mat4<T>& theMat) const
266 if (shape == gp_Identity)
268 theMat.InitIdentity();
272 theMat.SetValue (0, 0, static_cast<T> (Value (1, 1)));
273 theMat.SetValue (0, 1, static_cast<T> (Value (1, 2)));
274 theMat.SetValue (0, 2, static_cast<T> (Value (1, 3)));
275 theMat.SetValue (0, 3, static_cast<T> (Value (1, 4)));
276 theMat.SetValue (1, 0, static_cast<T> (Value (2, 1)));
277 theMat.SetValue (1, 1, static_cast<T> (Value (2, 2)));
278 theMat.SetValue (1, 2, static_cast<T> (Value (2, 3)));
279 theMat.SetValue (1, 3, static_cast<T> (Value (2, 4)));
280 theMat.SetValue (2, 0, static_cast<T> (Value (3, 1)));
281 theMat.SetValue (2, 1, static_cast<T> (Value (3, 2)));
282 theMat.SetValue (2, 2, static_cast<T> (Value (3, 3)));
283 theMat.SetValue (2, 3, static_cast<T> (Value (3, 4)));
284 theMat.SetValue (3, 0, static_cast<T> (0));
285 theMat.SetValue (3, 1, static_cast<T> (0));
286 theMat.SetValue (3, 2, static_cast<T> (0));
287 theMat.SetValue (3, 3, static_cast<T> (1));
290 //! Convert transformation from 4x4 matrix.
292 void SetMat4 (const NCollection_Mat4<T>& theMat)
296 matrix.SetValue (1, 1, theMat.GetValue (0, 0));
297 matrix.SetValue (1, 2, theMat.GetValue (0, 1));
298 matrix.SetValue (1, 3, theMat.GetValue (0, 2));
299 matrix.SetValue (2, 1, theMat.GetValue (1, 0));
300 matrix.SetValue (2, 2, theMat.GetValue (1, 1));
301 matrix.SetValue (2, 3, theMat.GetValue (1, 2));
302 matrix.SetValue (3, 1, theMat.GetValue (2, 0));
303 matrix.SetValue (3, 2, theMat.GetValue (2, 1));
304 matrix.SetValue (3, 3, theMat.GetValue (2, 2));
305 loc.SetCoord (theMat.GetValue (0, 3), theMat.GetValue (1, 3), theMat.GetValue (2, 3));
308 //! Dumps the content of me into the stream
309 Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
321 //=======================================================================
322 //function : SetAffinity
324 //=======================================================================
325 inline void gp_GTrsf::SetAffinity (const gp_Ax1& theA1, const Standard_Real theRatio)
329 matrix.SetDot (theA1.Direction().XYZ());
330 matrix.Multiply (1.0 - theRatio);
331 matrix.SetDiagonal (matrix.Value (1,1) + theRatio,
332 matrix.Value (2,2) + theRatio,
333 matrix.Value (3,3) + theRatio);
334 loc = theA1.Location().XYZ();
336 loc.Multiply (matrix);
337 loc.Add (theA1.Location().XYZ());
340 //=======================================================================
341 //function : SetAffinity
343 //=======================================================================
344 inline void gp_GTrsf::SetAffinity (const gp_Ax2& theA2, const Standard_Real theRatio)
348 matrix.SetDot (theA2.Direction().XYZ());
349 matrix.Multiply (theRatio - 1.);
350 loc = theA2.Location().XYZ();
352 loc.Multiply (matrix);
353 matrix.SetDiagonal (matrix.Value (1,1) + 1.,
354 matrix.Value (2,2) + 1.,
355 matrix.Value (3,3) + 1.);
358 //=======================================================================
359 //function : SetValue
361 //=======================================================================
362 inline void gp_GTrsf::SetValue (const Standard_Integer theRow,
363 const Standard_Integer theCol,
364 const Standard_Real theValue)
366 Standard_OutOfRange_Raise_if
367 (theRow < 1 || theRow > 3 || theCol < 1 || theCol > 4, " ");
370 loc.SetCoord (theRow, theValue);
371 if (shape == gp_Identity)
373 shape = gp_Translation;
379 if (!(shape == gp_Other) && !(scale == 1.0))
381 matrix.Multiply (scale);
383 matrix.SetValue (theRow, theCol, theValue);
390 //=======================================================================
393 //=======================================================================
394 inline Standard_Real gp_GTrsf::Value (const Standard_Integer theRow,
395 const Standard_Integer theCol) const
397 Standard_OutOfRange_Raise_if
398 (theRow < 1 || theRow > 3 || theCol < 1 || theCol > 4, " ");
401 return loc.Coord (theRow);
403 if (shape == gp_Other)
405 return matrix.Value (theRow, theCol);
407 return scale * matrix.Value (theRow, theCol);
410 //=======================================================================
411 //function : Transforms
413 //=======================================================================
414 inline void gp_GTrsf::Transforms (gp_XYZ& theCoord) const
416 theCoord.Multiply (matrix);
417 if (!(shape == gp_Other) && !(scale == 1.0))
419 theCoord.Multiply (scale);
424 //=======================================================================
425 //function : Transforms
427 //=======================================================================
428 inline void gp_GTrsf::Transforms (Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ) const
430 gp_XYZ aTriplet (theX, theY, theZ);
431 aTriplet.Multiply (matrix);
432 if (!(shape == gp_Other) && !(scale == 1.0))
434 aTriplet.Multiply (scale);
437 aTriplet.Coord (theX, theY, theZ);
440 //=======================================================================
443 //=======================================================================
444 inline gp_Trsf gp_GTrsf::Trsf() const
446 if (Form() == gp_Other)
448 throw Standard_ConstructionError("gp_GTrsf::Trsf() - non-orthogonal GTrsf");
458 #endif // _gp_GTrsf_HeaderFile