0032137: Coding Rules - merge redundant .lxx files into header files within Package gp
[occt.git] / src / gp / gp_Mat2d.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_Mat2d_HeaderFile
16 #define _gp_Mat2d_HeaderFile
17
18 #include <gp.hxx>
19 #include <Standard_ConstructionError.hxx>
20 #include <Standard_OutOfRange.hxx>
21
22 class gp_Trsf2d;
23 class gp_GTrsf2d;
24 class gp_XY;
25
26 #define Mat2d00 ((Standard_Real*)aM)[0]
27 #define Mat2d01 ((Standard_Real*)aM)[1]
28 #define Mat2d10 ((Standard_Real*)aM)[2]
29 #define Mat2d11 ((Standard_Real*)aM)[3]
30
31 #define Nat2d00 ((Standard_Real*)aN)[0]
32 #define Nat2d01 ((Standard_Real*)aN)[1]
33 #define Nat2d10 ((Standard_Real*)aN)[2]
34 #define Nat2d11 ((Standard_Real*)aN)[3]
35
36 #define Oat2d00 ((Standard_Real*)anO)[0]
37 #define Oat2d01 ((Standard_Real*)anO)[1]
38 #define Oat2d10 ((Standard_Real*)anO)[2]
39 #define Oat2d11 ((Standard_Real*)anO)[3]
40
41 //! Describes a two column, two row matrix. This sort of
42 //! object is used in various vectorial or matrix computations.
43 class gp_Mat2d 
44 {
45 public:
46
47   DEFINE_STANDARD_ALLOC
48
49   //! Creates  a matrix with null coefficients.
50   gp_Mat2d()
51   {
52     const Standard_Address aM = (Standard_Address)&(matrix[0][0]);
53     Mat2d00 = Mat2d01 = Mat2d10 = Mat2d11 = 0.0;
54   }
55
56   //! theCol1, theCol2 are the 2 columns of the matrix.
57   Standard_EXPORT gp_Mat2d (const gp_XY& theCol1, const gp_XY& theCol2);
58
59   //! Assigns the two coordinates of theValue to the column of range
60   //! theCol of this matrix
61   //! Raises OutOfRange if theCol < 1 or theCol > 2.
62   Standard_EXPORT void SetCol (const Standard_Integer theCol, const gp_XY& theValue);
63
64   //! Assigns the number pairs theCol1, theCol2 to the two columns of   this matrix
65   Standard_EXPORT void SetCols (const gp_XY& theCol1, const gp_XY& theCol2);
66
67   //! Modifies the main diagonal of the matrix.
68   //! @code
69   //! <me>.Value (1, 1) = theX1
70   //! <me>.Value (2, 2) = theX2
71   //! @endcode
72   //! The other coefficients of the matrix are not modified.
73   void SetDiagonal (const Standard_Real theX1, const Standard_Real theX2)
74   {
75     const Standard_Address aM = (Standard_Address)&(matrix[0][0]);
76     Mat2d00 = theX1;
77     Mat2d11 = theX2;
78   }
79
80   //! Modifies this matrix, so that it represents the Identity matrix.
81   void SetIdentity()
82   {
83     const Standard_Address aM = (Standard_Address)&(matrix[0][0]);
84     Mat2d00 = Mat2d11 = 1.0;
85     Mat2d01 = Mat2d10 = 0.0;
86   }
87
88   //! Modifies this matrix, so that it represents a rotation. theAng is the angular
89   //! value in radian of the rotation.
90   void SetRotation (const Standard_Real theAng);
91
92   //! Assigns the two coordinates of theValue to the row of index theRow of this matrix.
93   //! Raises OutOfRange if theRow < 1 or theRow > 2.
94   Standard_EXPORT void SetRow (const Standard_Integer theRow, const gp_XY& theValue);
95
96   //! Assigns the number pairs theRow1, theRow2 to the two rows of this matrix.
97   Standard_EXPORT void SetRows (const gp_XY& theRow1, const gp_XY& theRow2);
98
99   //! Modifies the matrix such that it
100   //! represents a scaling transformation, where theS is the scale   factor :
101   //! @code
102   //!         | theS    0.0 |
103   //! <me> =  | 0.0   theS  |
104   //! @endcode
105   void SetScale (const Standard_Real theS)
106   {
107     const Standard_Address aM = (Standard_Address)&(matrix[0][0]);
108     Mat2d00 = Mat2d11 = theS;
109     Mat2d01 = Mat2d10 = 0.0;
110   }
111
112   //! Assigns <theValue> to the coefficient of row theRow, column theCol of this matrix.
113   //! Raises OutOfRange if theRow < 1 or theRow > 2 or theCol < 1 or theCol > 2
114   void SetValue (const Standard_Integer theRow, const Standard_Integer theCol, const Standard_Real theValue)
115   {
116     Standard_OutOfRange_Raise_if (theRow < 1 || theRow > 2 || theCol < 1 || theCol > 2, " ");
117     matrix[theRow - 1][theCol - 1] = theValue;
118   }
119
120   //! Returns the column of theCol index.
121   //! Raises OutOfRange if theCol < 1 or theCol > 2
122   Standard_EXPORT gp_XY Column (const Standard_Integer theCol) const;
123
124   //! Computes the determinant of the matrix.
125   Standard_Real Determinant() const
126   {
127     const Standard_Address aM = (Standard_Address)&(matrix[0][0]);
128     return  Mat2d00 * Mat2d11 - Mat2d10 * Mat2d01;
129   }
130
131   //! Returns the main diagonal of the matrix.
132   Standard_EXPORT gp_XY Diagonal() const;
133
134   //! Returns the row of index theRow.
135   //! Raised if theRow < 1 or theRow > 2
136   Standard_EXPORT gp_XY Row (const Standard_Integer theRow) const;
137
138   //! Returns the coefficient of range (ttheheRow, theCol)
139   //! Raises OutOfRange
140   //! if theRow < 1 or theRow > 2 or theCol < 1 or theCol > 2
141   const Standard_Real& Value (const Standard_Integer theRow, const Standard_Integer theCol) const
142   {
143     Standard_OutOfRange_Raise_if (theRow < 1 || theRow > 2 || theCol < 1 || theCol > 2, " ");
144     return matrix[theRow - 1][theCol - 1];
145   }
146
147   const Standard_Real& operator() (const Standard_Integer theRow, const Standard_Integer theCol) const { return Value (theRow, theCol); }
148
149   //! Returns the coefficient of range (theRow, theCol)
150   //! Raises OutOfRange
151   //! if theRow < 1 or theRow > 2 or theCol < 1 or theCol > 2
152   Standard_Real& ChangeValue (const Standard_Integer theRow, const Standard_Integer theCol)
153   {
154     Standard_OutOfRange_Raise_if (theRow < 1 || theRow > 2 || theCol < 1 || theCol > 2, " ");
155     return matrix[theRow - 1][theCol - 1];
156   }
157
158   Standard_Real& operator() (const Standard_Integer theRow, const Standard_Integer theCol) { return ChangeValue (theRow, theCol); }
159
160   //! Returns true if this matrix is singular (and therefore, cannot be inverted).
161   //! The Gauss LU decomposition is used to invert the matrix
162   //! so the matrix is considered as singular if the largest
163   //! pivot found is lower or equal to Resolution from gp.
164   Standard_Boolean IsSingular() const
165   {
166     Standard_Real aDet = Determinant();
167     if (aDet < 0)
168     {
169       aDet = -aDet;
170     }
171     return aDet <= gp::Resolution();
172   }
173
174   void Add (const gp_Mat2d& Other);
175
176   void operator += (const gp_Mat2d& theOther) { Add (theOther); }
177
178   //! Computes the sum of this matrix and the matrix
179   //! theOther.for each coefficient of the matrix :
180   //! @code
181   //! <me>.Coef(i,j) + <theOther>.Coef(i,j)
182   //! @endcode
183   //! Note:
184   //! -   operator += assigns the result to this matrix, while
185   //! -   operator + creates a new one.
186   Standard_NODISCARD gp_Mat2d Added (const gp_Mat2d& theOther) const;
187
188   Standard_NODISCARD gp_Mat2d operator + (const gp_Mat2d& theOther) const { return Added (theOther); }
189
190   void Divide (const Standard_Real theScalar);
191
192   void operator /= (const Standard_Real theScalar) { Divide (theScalar); }
193
194   //! Divides all the coefficients of the matrix by a scalar.
195   Standard_NODISCARD gp_Mat2d Divided (const Standard_Real theScalar) const;
196
197   Standard_NODISCARD gp_Mat2d operator / (const Standard_Real theScalar) const { return Divided (theScalar); }
198
199   Standard_EXPORT void Invert();
200
201   //! Inverses the matrix and raises exception if the matrix
202   //! is singular.
203   Standard_NODISCARD gp_Mat2d Inverted() const
204   {
205     gp_Mat2d aNewMat = *this;
206     aNewMat.Invert();
207     return aNewMat;
208   }
209
210   Standard_NODISCARD gp_Mat2d Multiplied (const gp_Mat2d& theOther) const
211   {
212     gp_Mat2d aNewMat2d = *this;
213     aNewMat2d.Multiply (theOther);
214     return aNewMat2d;
215   }
216
217   Standard_NODISCARD gp_Mat2d operator * (const gp_Mat2d& theOther) const { return Multiplied (theOther); }
218
219   //! Computes the product of two matrices <me> * <theOther>
220   void Multiply (const gp_Mat2d& theOther);
221
222   //! Modifies this matrix by premultiplying it by the matrix Other
223   //! <me> = theOther * <me>.
224   void PreMultiply (const gp_Mat2d& theOther);
225
226   Standard_NODISCARD gp_Mat2d Multiplied (const Standard_Real theScalar) const;
227
228   Standard_NODISCARD gp_Mat2d operator * (const Standard_Real theScalar) const { return Multiplied (theScalar); }
229
230   //! Multiplies all the coefficients of the matrix by a scalar.
231   void Multiply (const Standard_Real theScalar);
232
233   void operator *= (const Standard_Real theScalar) { Multiply (theScalar); }
234
235   Standard_EXPORT void Power (const Standard_Integer theN);
236
237   //! computes <me> = <me> * <me> * .......* <me>, theN time.
238   //! if theN = 0 <me> = Identity
239   //! if theN < 0 <me> = <me>.Invert() *...........* <me>.Invert().
240   //! If theN < 0 an exception can be raised if the matrix is not
241   //! inversible
242   Standard_NODISCARD gp_Mat2d Powered (const Standard_Integer theN) const
243   {
244     gp_Mat2d aMat2dN = *this;
245     aMat2dN.Power (theN);
246     return aMat2dN;
247   }
248
249   void Subtract (const gp_Mat2d& theOther);
250
251   void operator -= (const gp_Mat2d& theOther) { Subtract (theOther); }
252
253   //! Computes for each coefficient of the matrix :
254   //! @code
255   //! <me>.Coef(i,j) - <theOther>.Coef(i,j)
256   //! @endcode
257   Standard_NODISCARD gp_Mat2d Subtracted (const gp_Mat2d& theOther) const;
258
259   Standard_NODISCARD gp_Mat2d operator - (const gp_Mat2d& theOther) const { return Subtracted (theOther); }
260
261   void Transpose();
262
263   //! Transposes the matrix. A(j, i) -> A (i, j)
264   Standard_NODISCARD gp_Mat2d Transposed() const;
265
266 friend class gp_Trsf2d;
267 friend class gp_GTrsf2d;
268 friend class gp_XY;
269
270 private:
271
272   Standard_Real matrix[2][2];
273
274 };
275
276 //=======================================================================
277 //function : SetRotation
278 // purpose :
279 //=======================================================================
280 inline void gp_Mat2d::SetRotation (const Standard_Real theAng)
281 {
282   const Standard_Address aM = (Standard_Address)&(matrix[0][0]);
283   Standard_Real aSinA = sin (theAng);
284   Standard_Real aCosA = cos (theAng);
285   Mat2d00 = Mat2d11 = aCosA;
286   Mat2d01 = -aSinA;
287   Mat2d10 =  aSinA;
288 }
289
290 //=======================================================================
291 //function : Add
292 // purpose :
293 //=======================================================================
294 inline void gp_Mat2d::Add (const gp_Mat2d& theOther)
295 {
296   const Standard_Address aM = (Standard_Address)&(matrix[0][0]);
297   const Standard_Address anO = (Standard_Address)&(theOther.matrix[0][0]);
298   Mat2d00 += Oat2d00;
299   Mat2d01 += Oat2d01;
300   Mat2d10 += Oat2d10;
301   Mat2d11 += Oat2d11;
302 }
303
304 //=======================================================================
305 //function : Added
306 // purpose :
307 //=======================================================================
308 inline gp_Mat2d gp_Mat2d::Added (const gp_Mat2d& theOther) const
309 {
310   gp_Mat2d aNewMat2d;
311   const Standard_Address aM = (Standard_Address)&(matrix[0][0]);
312   const Standard_Address aN = (Standard_Address)&(aNewMat2d.matrix[0][0]);
313   const Standard_Address anO = (Standard_Address)&(theOther   .matrix[0][0]);
314   Nat2d00 = Mat2d00 + Oat2d00;
315   Nat2d01 = Mat2d01 + Oat2d01;
316   Nat2d10 = Mat2d10 + Oat2d10;
317   Nat2d11 = Mat2d11 + Oat2d11;
318   return aNewMat2d;
319 }
320
321 //=======================================================================
322 //function : Divide
323 // purpose :
324 //=======================================================================
325 inline void gp_Mat2d::Divide (const Standard_Real theScalar)
326 {
327   const Standard_Address aM = (Standard_Address)&(matrix[0][0]);
328   Mat2d00 /= theScalar;
329   Mat2d01 /= theScalar;
330   Mat2d10 /= theScalar;
331   Mat2d11 /= theScalar;
332 }
333
334 //=======================================================================
335 //function : Divided
336 // purpose :
337 //=======================================================================
338 inline gp_Mat2d gp_Mat2d::Divided (const Standard_Real theScalar) const
339 {
340   gp_Mat2d aNewMat2d;
341   const Standard_Address aM = (Standard_Address)&(matrix[0][0]);
342   const Standard_Address aN = (Standard_Address)&(aNewMat2d.matrix[0][0]);
343   Nat2d00 = Mat2d00 / theScalar;
344   Nat2d01 = Mat2d01 / theScalar;
345   Nat2d10 = Mat2d10 / theScalar;
346   Nat2d11 = Mat2d11 / theScalar;
347   return aNewMat2d;
348 }
349
350 //=======================================================================
351 //function : Multiply
352 // purpose :
353 //=======================================================================
354 inline void gp_Mat2d::Multiply (const gp_Mat2d& theOther)
355 {
356   Standard_Real aT00, aT10;
357   const Standard_Address aM = (Standard_Address)&(matrix[0][0]);
358   const Standard_Address anO = (Standard_Address)&(theOther.matrix[0][0]);
359   aT00 = Mat2d00 * Oat2d00 + Mat2d01 * Oat2d10;
360   aT10 = Mat2d10 * Oat2d00 + Mat2d11 * Oat2d10;
361   Mat2d01 = Mat2d00 * Oat2d01 + Mat2d01 * Oat2d11;
362   Mat2d11 = Mat2d10 * Oat2d01 + Mat2d11 * Oat2d11;
363   Mat2d00 = aT00;
364   Mat2d10 = aT10;
365 }
366
367 //=======================================================================
368 //function : PreMultiply
369 // purpose :
370 //=======================================================================
371 inline void gp_Mat2d::PreMultiply (const gp_Mat2d& theOther)
372 {
373   Standard_Real aT00, aT01;
374   const Standard_Address aM = (Standard_Address)&(matrix[0][0]);
375   const Standard_Address anO = (Standard_Address)&(theOther.matrix[0][0]);
376   aT00 = Oat2d00 * Mat2d00 + Oat2d01 * Mat2d10;
377   Mat2d10 = Oat2d10 * Mat2d00 + Oat2d11 * Mat2d10;
378   aT01 = Oat2d00 * Mat2d01 + Oat2d01 * Mat2d11;
379   Mat2d11 = Oat2d10 * Mat2d01 + Oat2d11 * Mat2d11;
380   Mat2d00 = aT00;
381   Mat2d01 = aT01;
382 }
383
384 //=======================================================================
385 //function : Multiplied
386 // purpose :
387 //=======================================================================
388 inline gp_Mat2d gp_Mat2d::Multiplied (const Standard_Real theScalar) const
389 {
390   gp_Mat2d aNewMat2d;
391   const Standard_Address aM = (Standard_Address)&(matrix[0][0]);
392   const Standard_Address aN = (Standard_Address)&(aNewMat2d.matrix[0][0]);
393   Nat2d00 = Mat2d00 * theScalar;
394   Nat2d01 = Mat2d01 * theScalar;
395   Nat2d10 = Mat2d10 * theScalar;
396   Nat2d11 = Mat2d11 * theScalar;
397   return aNewMat2d;
398 }
399
400 //=======================================================================
401 //function : Multiply
402 // purpose :
403 //=======================================================================
404 inline void gp_Mat2d::Multiply (const Standard_Real theScalar)
405 {
406   const Standard_Address aM = (Standard_Address)&(matrix[0][0]);
407   Mat2d00 *= theScalar;
408   Mat2d01 *= theScalar;
409   Mat2d10 *= theScalar;
410   Mat2d11 *= theScalar;
411 }
412
413 //=======================================================================
414 //function : Subtract
415 // purpose :
416 //=======================================================================
417 inline void gp_Mat2d::Subtract (const gp_Mat2d& theOther)
418 {
419   const Standard_Address aM = (Standard_Address)&(matrix[0][0]);
420   const Standard_Address anO = (Standard_Address)&(theOther.matrix[0][0]);
421   Mat2d00 -= Oat2d00;
422   Mat2d01 -= Oat2d01;
423   Mat2d10 -= Oat2d10;
424   Mat2d11 -= Oat2d11;
425 }
426
427 //=======================================================================
428 //function : Subtracted
429 // purpose :
430 //=======================================================================
431 inline gp_Mat2d gp_Mat2d::Subtracted (const gp_Mat2d& theOther) const
432 {
433   gp_Mat2d aNewMat2d;
434   const Standard_Address aM = (Standard_Address)&(matrix[0][0]);
435   const Standard_Address aN = (Standard_Address)&(aNewMat2d.matrix[0][0]);
436   const Standard_Address anO = (Standard_Address)&(theOther.matrix[0][0]);
437   Nat2d00 = Mat2d00 - Oat2d00;
438   Nat2d01 = Mat2d01 - Oat2d01;
439   Nat2d10 = Mat2d10 - Oat2d10;
440   Nat2d11 = Mat2d11 - Oat2d11;
441   return aNewMat2d;
442 }
443
444 //=======================================================================
445 //function : Transpose
446 // purpose :
447 //=======================================================================
448 inline void gp_Mat2d::Transpose()
449 {
450   const Standard_Address aM = (Standard_Address)&(matrix[0][0]);
451   Standard_Real aTemp;
452   aTemp     = Mat2d01;
453   Mat2d01  = Mat2d10;
454   Mat2d10  = aTemp;
455 }
456
457 //=======================================================================
458 //function : Transposed
459 // purpose :
460 //=======================================================================
461 inline gp_Mat2d gp_Mat2d::Transposed() const
462 {
463   gp_Mat2d aNewMat2d;
464   const Standard_Address aM = (Standard_Address)&(matrix[0][0]);
465   const Standard_Address aN = (Standard_Address)&(aNewMat2d.matrix[0][0]);
466   Nat2d10 = Mat2d01;
467   Nat2d01 = Mat2d10;
468   Nat2d00 = Mat2d00;
469   Nat2d11 = Mat2d11;
470   return aNewMat2d; 
471 }
472
473 //=======================================================================
474 //function : operator*
475 // purpose :
476 //=======================================================================
477 inline gp_Mat2d operator* (const Standard_Real theScalar, const gp_Mat2d& theMat2D)
478 {
479   return theMat2D.Multiplied (theScalar);
480 }
481
482 #endif // _gp_Mat2d_HeaderFile