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_Mat_HeaderFile |
16 | #define _gp_Mat_HeaderFile |
17 | |
d5477f8c |
18 | #include <gp.hxx> |
19 | #include <Standard_OutOfRange.hxx> |
92f8ec2f |
20 | #include <Standard_OStream.hxx> |
d5477f8c |
21 | #include <Standard_ConstructionError.hxx> |
92f8ec2f |
22 | |
42cf5bc1 |
23 | class gp_XYZ; |
24 | class gp_Trsf; |
25 | class gp_GTrsf; |
26 | |
623e54f9 |
27 | //! Describes a three column, three row matrix. |
28 | //! This sort of object is used in various vectorial or matrix computations. |
42cf5bc1 |
29 | class gp_Mat |
30 | { |
31 | public: |
32 | |
33 | DEFINE_STANDARD_ALLOC |
34 | |
42cf5bc1 |
35 | //! creates a matrix with null coefficients. |
d5477f8c |
36 | gp_Mat() |
37 | { |
623e54f9 |
38 | myMat[0][0] = myMat[0][1] = myMat[0][2] = |
39 | myMat[1][0] = myMat[1][1] = myMat[1][2] = |
40 | myMat[2][0] = myMat[2][1] = myMat[2][2] = 0.0; |
d5477f8c |
41 | } |
42 | |
43 | gp_Mat (const Standard_Real theA11, const Standard_Real theA12, const Standard_Real theA13, |
44 | const Standard_Real theA21, const Standard_Real theA22, const Standard_Real theA23, |
45 | const Standard_Real theA31, const Standard_Real theA32, const Standard_Real theA33); |
46 | |
42cf5bc1 |
47 | //! Creates a matrix. |
d5477f8c |
48 | //! theCol1, theCol2, theCol3 are the 3 columns of the matrix. |
49 | Standard_EXPORT gp_Mat (const gp_XYZ& theCol1, const gp_XYZ& theCol2, const gp_XYZ& theCol3); |
50 | |
51 | //! Assigns the three coordinates of theValue to the column of index |
52 | //! theCol of this matrix. |
53 | //! Raises OutOfRange if theCol < 1 or theCol > 3. |
54 | Standard_EXPORT void SetCol (const Standard_Integer theCol, const gp_XYZ& theValue); |
55 | |
56 | //! Assigns the number triples theCol1, theCol2, theCol3 to the three |
42cf5bc1 |
57 | //! columns of this matrix. |
d5477f8c |
58 | Standard_EXPORT void SetCols (const gp_XYZ& theCol1, const gp_XYZ& theCol2, const gp_XYZ& theCol3); |
42cf5bc1 |
59 | |
60 | //! Modifies the matrix M so that applying it to any number |
61 | //! triple (X, Y, Z) produces the same result as the cross |
d5477f8c |
62 | //! product of theRef and the number triple (X, Y, Z): |
63 | //! i.e.: M * {X,Y,Z}t = theRef.Cross({X, Y ,Z}) |
42cf5bc1 |
64 | //! this matrix is anti symmetric. To apply this matrix to the |
65 | //! triplet {XYZ} is the same as to do the cross product between the |
d5477f8c |
66 | //! triplet theRef and the triplet {XYZ}. |
42cf5bc1 |
67 | //! Note: this matrix is anti-symmetric. |
d5477f8c |
68 | Standard_EXPORT void SetCross (const gp_XYZ& theRef); |
42cf5bc1 |
69 | |
70 | //! Modifies the main diagonal of the matrix. |
08eda8e3 |
71 | //! @code |
d5477f8c |
72 | //! <me>.Value (1, 1) = theX1 |
73 | //! <me>.Value (2, 2) = theX2 |
74 | //! <me>.Value (3, 3) = theX3 |
08eda8e3 |
75 | //! @endcode |
42cf5bc1 |
76 | //! The other coefficients of the matrix are not modified. |
d5477f8c |
77 | void SetDiagonal (const Standard_Real theX1, const Standard_Real theX2, const Standard_Real theX3) |
78 | { |
623e54f9 |
79 | myMat[0][0] = theX1; |
80 | myMat[1][1] = theX2; |
81 | myMat[2][2] = theX3; |
d5477f8c |
82 | } |
42cf5bc1 |
83 | |
84 | //! Modifies this matrix so that applying it to any number |
85 | //! triple (X, Y, Z) produces the same result as the scalar |
d5477f8c |
86 | //! product of theRef and the number triple (X, Y, Z): |
87 | //! this * (X,Y,Z) = theRef.(X,Y,Z) |
42cf5bc1 |
88 | //! Note: this matrix is symmetric. |
d5477f8c |
89 | Standard_EXPORT void SetDot (const gp_XYZ& theRef); |
90 | |
42cf5bc1 |
91 | //! Modifies this matrix so that it represents the Identity matrix. |
d5477f8c |
92 | void SetIdentity() |
93 | { |
623e54f9 |
94 | myMat[0][0] = myMat[1][1] = myMat[2][2] = 1.0; |
95 | myMat[0][1] = myMat[0][2] = myMat[1][0] = myMat[1][2] = myMat[2][0] = myMat[2][1] = 0.0; |
d5477f8c |
96 | } |
42cf5bc1 |
97 | |
d5477f8c |
98 | //! Modifies this matrix so that it represents a rotation. theAng is the angular value in |
42cf5bc1 |
99 | //! radians and the XYZ axis gives the direction of the |
100 | //! rotation. |
101 | //! Raises ConstructionError if XYZ.Modulus() <= Resolution() |
d5477f8c |
102 | Standard_EXPORT void SetRotation (const gp_XYZ& theAxis, const Standard_Real theAng); |
103 | |
42cf5bc1 |
104 | //! Assigns the three coordinates of Value to the row of index |
d5477f8c |
105 | //! theRow of this matrix. Raises OutOfRange if theRow < 1 or theRow > 3. |
106 | Standard_EXPORT void SetRow (const Standard_Integer theRow, const gp_XYZ& theValue); |
107 | |
108 | //! Assigns the number triples theRow1, theRow2, theRow3 to the three |
42cf5bc1 |
109 | //! rows of this matrix. |
d5477f8c |
110 | Standard_EXPORT void SetRows (const gp_XYZ& theRow1, const gp_XYZ& theRow2, const gp_XYZ& theRow3); |
42cf5bc1 |
111 | |
54adc5e9 |
112 | //! Modifies the matrix so that it represents |
d5477f8c |
113 | //! a scaling transformation, where theS is the scale factor. : |
08eda8e3 |
114 | //! @code |
d5477f8c |
115 | //! | theS 0.0 0.0 | |
116 | //! <me> = | 0.0 theS 0.0 | |
117 | //! | 0.0 0.0 theS | |
08eda8e3 |
118 | //! @endcode |
d5477f8c |
119 | void SetScale (const Standard_Real theS) |
120 | { |
623e54f9 |
121 | myMat[0][0] = myMat[1][1] = myMat[2][2] = theS; |
122 | myMat[0][1] = myMat[0][2] = myMat[1][0] = myMat[1][2] = myMat[2][0] = myMat[2][1] = 0.0; |
d5477f8c |
123 | } |
124 | |
125 | //! Assigns <theValue> to the coefficient of row theRow, column theCol of this matrix. |
126 | //! Raises OutOfRange if theRow < 1 or theRow > 3 or theCol < 1 or theCol > 3 |
127 | void SetValue (const Standard_Integer theRow, const Standard_Integer theCol, const Standard_Real theValue) |
128 | { |
129 | Standard_OutOfRange_Raise_if (theRow < 1 || theRow > 3 || theCol < 1 || theCol > 3, " "); |
623e54f9 |
130 | myMat[theRow - 1][theCol - 1] = theValue; |
d5477f8c |
131 | } |
132 | |
133 | //! Returns the column of theCol index. |
134 | //! Raises OutOfRange if theCol < 1 or theCol > 3 |
135 | Standard_EXPORT gp_XYZ Column (const Standard_Integer theCol) const; |
136 | |
42cf5bc1 |
137 | //! Computes the determinant of the matrix. |
d5477f8c |
138 | Standard_Real Determinant() const |
139 | { |
623e54f9 |
140 | return myMat[0][0] * (myMat[1][1] * myMat[2][2] - myMat[2][1] * myMat[1][2]) - |
141 | myMat[0][1] * (myMat[1][0] * myMat[2][2] - myMat[2][0] * myMat[1][2]) + |
142 | myMat[0][2] * (myMat[1][0] * myMat[2][1] - myMat[2][0] * myMat[1][1]); |
d5477f8c |
143 | } |
144 | |
42cf5bc1 |
145 | //! Returns the main diagonal of the matrix. |
146 | Standard_EXPORT gp_XYZ Diagonal() const; |
d5477f8c |
147 | |
148 | //! returns the row of theRow index. |
149 | //! Raises OutOfRange if theRow < 1 or theRow > 3 |
150 | Standard_EXPORT gp_XYZ Row (const Standard_Integer theRow) const; |
151 | |
152 | //! Returns the coefficient of range (theRow, theCol) |
153 | //! Raises OutOfRange if theRow < 1 or theRow > 3 or theCol < 1 or theCol > 3 |
154 | const Standard_Real& Value (const Standard_Integer theRow, const Standard_Integer theCol) const |
155 | { |
156 | Standard_OutOfRange_Raise_if (theRow < 1 || theRow > 3 || theCol < 1 || theCol > 3, " "); |
623e54f9 |
157 | return myMat[theRow - 1][theCol - 1]; |
d5477f8c |
158 | } |
159 | |
160 | const Standard_Real& operator() (const Standard_Integer theRow, const Standard_Integer theCol) const { return Value (theRow, theCol); } |
161 | |
162 | //! Returns the coefficient of range (theRow, theCol) |
163 | //! Raises OutOfRange if theRow < 1 or theRow > 3 or theCol < 1 or theCol > 3 |
164 | Standard_Real& ChangeValue (const Standard_Integer theRow, const Standard_Integer theCol) |
165 | { |
166 | Standard_OutOfRange_Raise_if (theRow < 1 || theRow > 3 || theCol < 1 || theCol > 3, " "); |
623e54f9 |
167 | return myMat[theRow - 1][theCol - 1]; |
d5477f8c |
168 | } |
169 | |
170 | Standard_Real& operator() (const Standard_Integer theRow, const Standard_Integer theCol) { return ChangeValue (theRow, theCol); } |
42cf5bc1 |
171 | |
172 | //! The Gauss LU decomposition is used to invert the matrix |
173 | //! (see Math package) so the matrix is considered as singular if |
174 | //! the largest pivot found is lower or equal to Resolution from gp. |
d5477f8c |
175 | Standard_Boolean IsSingular() const |
176 | { |
177 | // Pour etre sur que Gauss va fonctionner, il faut faire Gauss ... |
178 | Standard_Real aVal = Determinant(); |
179 | if (aVal < 0) |
180 | { |
181 | aVal = -aVal; |
182 | } |
183 | return aVal <= gp::Resolution(); |
184 | } |
185 | |
186 | void Add (const gp_Mat& theOther); |
187 | |
188 | void operator += (const gp_Mat& theOther) { Add (theOther); } |
189 | |
42cf5bc1 |
190 | //! Computes the sum of this matrix and |
d5477f8c |
191 | //! the matrix theOther for each coefficient of the matrix : |
192 | //! <me>.Coef(i,j) + <theOther>.Coef(i,j) |
193 | Standard_NODISCARD gp_Mat Added (const gp_Mat& theOther) const; |
194 | |
195 | Standard_NODISCARD gp_Mat operator + (const gp_Mat& theOther) const { return Added (theOther); } |
196 | |
197 | void Divide (const Standard_Real theScalar); |
198 | |
199 | void operator /= (const Standard_Real theScalar) { Divide (theScalar); } |
200 | |
42cf5bc1 |
201 | //! Divides all the coefficients of the matrix by Scalar |
d5477f8c |
202 | Standard_NODISCARD gp_Mat Divided (const Standard_Real theScalar) const; |
203 | |
204 | Standard_NODISCARD gp_Mat operator / (const Standard_Real theScalar) const { return Divided (theScalar); } |
205 | |
42cf5bc1 |
206 | Standard_EXPORT void Invert(); |
42cf5bc1 |
207 | |
208 | //! Inverses the matrix and raises if the matrix is singular. |
209 | //! - Invert assigns the result to this matrix, while |
210 | //! - Inverted creates a new one. |
211 | //! Warning |
212 | //! The Gauss LU decomposition is used to invert the matrix. |
213 | //! Consequently, the matrix is considered as singular if the |
214 | //! largest pivot found is less than or equal to gp::Resolution(). |
215 | //! Exceptions |
216 | //! Standard_ConstructionError if this matrix is singular, |
217 | //! and therefore cannot be inverted. |
0be7dbe1 |
218 | Standard_NODISCARD Standard_EXPORT gp_Mat Inverted() const; |
42cf5bc1 |
219 | |
220 | //! Computes the product of two matrices <me> * <Other> |
d5477f8c |
221 | Standard_NODISCARD gp_Mat Multiplied (const gp_Mat& theOther) const |
222 | { |
223 | gp_Mat aNewMat = *this; |
224 | aNewMat.Multiply (theOther); |
225 | return aNewMat; |
226 | } |
227 | |
228 | Standard_NODISCARD gp_Mat operator * (const gp_Mat& theOther) const { return Multiplied (theOther); } |
229 | |
42cf5bc1 |
230 | //! Computes the product of two matrices <me> = <Other> * <me>. |
d5477f8c |
231 | void Multiply (const gp_Mat& theOther); |
232 | |
233 | void operator *= (const gp_Mat& theOther) { Multiply (theOther); } |
234 | |
235 | void PreMultiply (const gp_Mat& theOther); |
236 | |
237 | Standard_NODISCARD gp_Mat Multiplied (const Standard_Real theScalar) const; |
238 | |
239 | Standard_NODISCARD gp_Mat operator * (const Standard_Real theScalar) const { return Multiplied (theScalar); } |
42cf5bc1 |
240 | |
241 | //! Multiplies all the coefficients of the matrix by Scalar |
d5477f8c |
242 | void Multiply (const Standard_Real theScalar); |
243 | |
244 | void operator *= (const Standard_Real theScalar) { Multiply (theScalar); } |
245 | |
42cf5bc1 |
246 | Standard_EXPORT void Power (const Standard_Integer N); |
42cf5bc1 |
247 | |
d5477f8c |
248 | //! Computes <me> = <me> * <me> * .......* <me>, theN time. |
249 | //! if theN = 0 <me> = Identity |
250 | //! if theN < 0 <me> = <me>.Invert() *...........* <me>.Invert(). |
251 | //! If theN < 0 an exception will be raised if the matrix is not |
42cf5bc1 |
252 | //! inversible |
d5477f8c |
253 | Standard_NODISCARD gp_Mat Powered (const Standard_Integer theN) const |
254 | { |
255 | gp_Mat aMatN = *this; |
256 | aMatN.Power (theN); |
257 | return aMatN; |
258 | } |
259 | |
260 | void Subtract (const gp_Mat& theOther); |
261 | |
262 | void operator -= (const gp_Mat& theOther) { Subtract (theOther); } |
42cf5bc1 |
263 | |
264 | //! cOmputes for each coefficient of the matrix : |
d5477f8c |
265 | //! <me>.Coef(i,j) - <theOther>.Coef(i,j) |
266 | Standard_NODISCARD gp_Mat Subtracted (const gp_Mat& theOther) const; |
267 | |
268 | Standard_NODISCARD gp_Mat operator - (const gp_Mat& theOther) const { return Subtracted (theOther); } |
269 | |
270 | void Transpose(); |
42cf5bc1 |
271 | |
272 | //! Transposes the matrix. A(j, i) -> A (i, j) |
d5477f8c |
273 | Standard_NODISCARD gp_Mat Transposed() const |
274 | { |
275 | gp_Mat aNewMat = *this; |
276 | aNewMat.Transpose(); |
277 | return aNewMat; |
278 | } |
42cf5bc1 |
279 | |
0904aa63 |
280 | //! Dumps the content of me into the stream |
bc73b006 |
281 | Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const; |
0904aa63 |
282 | |
42cf5bc1 |
283 | friend class gp_XYZ; |
284 | friend class gp_Trsf; |
285 | friend class gp_GTrsf; |
286 | |
d5477f8c |
287 | private: |
42cf5bc1 |
288 | |
623e54f9 |
289 | Standard_Real myMat[3][3]; |
42cf5bc1 |
290 | |
d5477f8c |
291 | }; |
42cf5bc1 |
292 | |
d5477f8c |
293 | //======================================================================= |
294 | //function : gp_Mat |
295 | // purpose : |
296 | //======================================================================= |
297 | inline gp_Mat::gp_Mat (const Standard_Real theA11, const Standard_Real theA12, const Standard_Real theA13, |
298 | const Standard_Real theA21, const Standard_Real theA22, const Standard_Real theA23, |
299 | const Standard_Real theA31, const Standard_Real theA32, const Standard_Real theA33) |
623e54f9 |
300 | { |
301 | myMat[0][0] = theA11; |
302 | myMat[0][1] = theA12; |
303 | myMat[0][2] = theA13; |
304 | myMat[1][0] = theA21; |
305 | myMat[1][1] = theA22; |
306 | myMat[1][2] = theA23; |
307 | myMat[2][0] = theA31; |
308 | myMat[2][1] = theA32; |
309 | myMat[2][2] = theA33; |
310 | } |
d5477f8c |
311 | |
312 | //======================================================================= |
313 | //function : Add |
314 | // purpose : |
315 | //======================================================================= |
316 | inline void gp_Mat::Add (const gp_Mat& theOther) |
317 | { |
623e54f9 |
318 | myMat[0][0] += theOther.myMat[0][0]; |
319 | myMat[0][1] += theOther.myMat[0][1]; |
320 | myMat[0][2] += theOther.myMat[0][2]; |
321 | myMat[1][0] += theOther.myMat[1][0]; |
322 | myMat[1][1] += theOther.myMat[1][1]; |
323 | myMat[1][2] += theOther.myMat[1][2]; |
324 | myMat[2][0] += theOther.myMat[2][0]; |
325 | myMat[2][1] += theOther.myMat[2][1]; |
326 | myMat[2][2] += theOther.myMat[2][2]; |
d5477f8c |
327 | } |
42cf5bc1 |
328 | |
d5477f8c |
329 | //======================================================================= |
330 | //function : Added |
331 | // purpose : |
332 | //======================================================================= |
333 | inline gp_Mat gp_Mat::Added (const gp_Mat& theOther) const |
334 | { |
335 | gp_Mat aNewMat; |
623e54f9 |
336 | aNewMat.myMat[0][0] = myMat[0][0] + theOther.myMat[0][0]; |
337 | aNewMat.myMat[0][1] = myMat[0][1] + theOther.myMat[0][1]; |
338 | aNewMat.myMat[0][2] = myMat[0][2] + theOther.myMat[0][2]; |
339 | aNewMat.myMat[1][0] = myMat[1][0] + theOther.myMat[1][0]; |
340 | aNewMat.myMat[1][1] = myMat[1][1] + theOther.myMat[1][1]; |
341 | aNewMat.myMat[1][2] = myMat[1][2] + theOther.myMat[1][2]; |
342 | aNewMat.myMat[2][0] = myMat[2][0] + theOther.myMat[2][0]; |
343 | aNewMat.myMat[2][1] = myMat[2][1] + theOther.myMat[2][1]; |
344 | aNewMat.myMat[2][2] = myMat[2][2] + theOther.myMat[2][2]; |
d5477f8c |
345 | return aNewMat; |
346 | } |
42cf5bc1 |
347 | |
d5477f8c |
348 | //======================================================================= |
349 | //function : Divide |
350 | // purpose : |
351 | //======================================================================= |
352 | inline void gp_Mat::Divide (const Standard_Real theScalar) |
353 | { |
354 | Standard_Real aVal = theScalar; |
355 | if (aVal < 0) |
356 | { |
357 | aVal = -aVal; |
358 | } |
359 | Standard_ConstructionError_Raise_if (aVal <= gp::Resolution(),"gp_Mat : Divide by 0"); |
623e54f9 |
360 | const Standard_Real anUnSurScalar = 1.0 / theScalar; |
361 | myMat[0][0] *= anUnSurScalar; |
362 | myMat[0][1] *= anUnSurScalar; |
363 | myMat[0][2] *= anUnSurScalar; |
364 | myMat[1][0] *= anUnSurScalar; |
365 | myMat[1][1] *= anUnSurScalar; |
366 | myMat[1][2] *= anUnSurScalar; |
367 | myMat[2][0] *= anUnSurScalar; |
368 | myMat[2][1] *= anUnSurScalar; |
369 | myMat[2][2] *= anUnSurScalar; |
d5477f8c |
370 | } |
42cf5bc1 |
371 | |
d5477f8c |
372 | //======================================================================= |
373 | //function : Divided |
374 | // purpose : |
375 | //======================================================================= |
376 | inline gp_Mat gp_Mat::Divided (const Standard_Real theScalar) const |
377 | { |
378 | Standard_Real aVal = theScalar; |
379 | if (aVal < 0) |
380 | { |
381 | aVal = -aVal; |
382 | } |
383 | Standard_ConstructionError_Raise_if (aVal <= gp::Resolution(),"gp_Mat : Divide by 0"); |
384 | gp_Mat aNewMat; |
623e54f9 |
385 | const Standard_Real anUnSurScalar = 1.0 / theScalar; |
386 | aNewMat.myMat[0][0] = myMat[0][0] * anUnSurScalar; |
387 | aNewMat.myMat[0][1] = myMat[0][1] * anUnSurScalar; |
388 | aNewMat.myMat[0][2] = myMat[0][2] * anUnSurScalar; |
389 | aNewMat.myMat[1][0] = myMat[1][0] * anUnSurScalar; |
390 | aNewMat.myMat[1][1] = myMat[1][1] * anUnSurScalar; |
391 | aNewMat.myMat[1][2] = myMat[1][2] * anUnSurScalar; |
392 | aNewMat.myMat[2][0] = myMat[2][0] * anUnSurScalar; |
393 | aNewMat.myMat[2][1] = myMat[2][1] * anUnSurScalar; |
394 | aNewMat.myMat[2][2] = myMat[2][2] * anUnSurScalar; |
d5477f8c |
395 | return aNewMat; |
396 | } |
42cf5bc1 |
397 | |
d5477f8c |
398 | //======================================================================= |
399 | //function : Multiply |
400 | // purpose : |
401 | //======================================================================= |
402 | inline void gp_Mat::Multiply (const gp_Mat& theOther) |
403 | { |
623e54f9 |
404 | const Standard_Real aT00 = myMat[0][0] * theOther.myMat[0][0] + myMat[0][1] * theOther.myMat[1][0] + myMat[0][2] * theOther.myMat[2][0]; |
405 | const Standard_Real aT01 = myMat[0][0] * theOther.myMat[0][1] + myMat[0][1] * theOther.myMat[1][1] + myMat[0][2] * theOther.myMat[2][1]; |
406 | const Standard_Real aT02 = myMat[0][0] * theOther.myMat[0][2] + myMat[0][1] * theOther.myMat[1][2] + myMat[0][2] * theOther.myMat[2][2]; |
407 | const Standard_Real aT10 = myMat[1][0] * theOther.myMat[0][0] + myMat[1][1] * theOther.myMat[1][0] + myMat[1][2] * theOther.myMat[2][0]; |
408 | const Standard_Real aT11 = myMat[1][0] * theOther.myMat[0][1] + myMat[1][1] * theOther.myMat[1][1] + myMat[1][2] * theOther.myMat[2][1]; |
409 | const Standard_Real aT12 = myMat[1][0] * theOther.myMat[0][2] + myMat[1][1] * theOther.myMat[1][2] + myMat[1][2] * theOther.myMat[2][2]; |
410 | const Standard_Real aT20 = myMat[2][0] * theOther.myMat[0][0] + myMat[2][1] * theOther.myMat[1][0] + myMat[2][2] * theOther.myMat[2][0]; |
411 | const Standard_Real aT21 = myMat[2][0] * theOther.myMat[0][1] + myMat[2][1] * theOther.myMat[1][1] + myMat[2][2] * theOther.myMat[2][1]; |
412 | const Standard_Real aT22 = myMat[2][0] * theOther.myMat[0][2] + myMat[2][1] * theOther.myMat[1][2] + myMat[2][2] * theOther.myMat[2][2]; |
413 | myMat[0][0] = aT00; |
414 | myMat[0][1] = aT01; |
415 | myMat[0][2] = aT02; |
416 | myMat[1][0] = aT10; |
417 | myMat[1][1] = aT11; |
418 | myMat[1][2] = aT12; |
419 | myMat[2][0] = aT20; |
420 | myMat[2][1] = aT21; |
421 | myMat[2][2] = aT22; |
d5477f8c |
422 | } |
42cf5bc1 |
423 | |
d5477f8c |
424 | //======================================================================= |
425 | //function : PreMultiply |
426 | // purpose : |
427 | //======================================================================= |
428 | inline void gp_Mat::PreMultiply (const gp_Mat& theOther) |
429 | { |
623e54f9 |
430 | const Standard_Real aT00 = theOther.myMat[0][0] * myMat[0][0] + theOther.myMat[0][1] * myMat[1][0] + theOther.myMat[0][2] * myMat[2][0]; |
431 | const Standard_Real aT01 = theOther.myMat[0][0] * myMat[0][1] + theOther.myMat[0][1] * myMat[1][1] + theOther.myMat[0][2] * myMat[2][1]; |
432 | const Standard_Real aT02 = theOther.myMat[0][0] * myMat[0][2] + theOther.myMat[0][1] * myMat[1][2] + theOther.myMat[0][2] * myMat[2][2]; |
433 | const Standard_Real aT10 = theOther.myMat[1][0] * myMat[0][0] + theOther.myMat[1][1] * myMat[1][0] + theOther.myMat[1][2] * myMat[2][0]; |
434 | const Standard_Real aT11 = theOther.myMat[1][0] * myMat[0][1] + theOther.myMat[1][1] * myMat[1][1] + theOther.myMat[1][2] * myMat[2][1]; |
435 | const Standard_Real aT12 = theOther.myMat[1][0] * myMat[0][2] + theOther.myMat[1][1] * myMat[1][2] + theOther.myMat[1][2] * myMat[2][2]; |
436 | const Standard_Real aT20 = theOther.myMat[2][0] * myMat[0][0] + theOther.myMat[2][1] * myMat[1][0] + theOther.myMat[2][2] * myMat[2][0]; |
437 | const Standard_Real aT21 = theOther.myMat[2][0] * myMat[0][1] + theOther.myMat[2][1] * myMat[1][1] + theOther.myMat[2][2] * myMat[2][1]; |
438 | const Standard_Real aT22 = theOther.myMat[2][0] * myMat[0][2] + theOther.myMat[2][1] * myMat[1][2] + theOther.myMat[2][2] * myMat[2][2]; |
439 | myMat[0][0] = aT00; |
440 | myMat[0][1] = aT01; |
441 | myMat[0][2] = aT02; |
442 | myMat[1][0] = aT10; |
443 | myMat[1][1] = aT11; |
444 | myMat[1][2] = aT12; |
445 | myMat[2][0] = aT20; |
446 | myMat[2][1] = aT21; |
447 | myMat[2][2] = aT22; |
d5477f8c |
448 | } |
42cf5bc1 |
449 | |
d5477f8c |
450 | //======================================================================= |
451 | //function : Multiplied |
452 | // purpose : |
453 | //======================================================================= |
454 | inline gp_Mat gp_Mat::Multiplied (const Standard_Real theScalar) const |
455 | { |
456 | gp_Mat aNewMat; |
623e54f9 |
457 | aNewMat.myMat[0][0] = theScalar * myMat[0][0]; |
458 | aNewMat.myMat[0][1] = theScalar * myMat[0][1]; |
459 | aNewMat.myMat[0][2] = theScalar * myMat[0][2]; |
460 | aNewMat.myMat[1][0] = theScalar * myMat[1][0]; |
461 | aNewMat.myMat[1][1] = theScalar * myMat[1][1]; |
462 | aNewMat.myMat[1][2] = theScalar * myMat[1][2]; |
463 | aNewMat.myMat[2][0] = theScalar * myMat[2][0]; |
464 | aNewMat.myMat[2][1] = theScalar * myMat[2][1]; |
465 | aNewMat.myMat[2][2] = theScalar * myMat[2][2]; |
d5477f8c |
466 | return aNewMat; |
467 | } |
42cf5bc1 |
468 | |
d5477f8c |
469 | //======================================================================= |
470 | //function : Multiply |
471 | // purpose : |
472 | //======================================================================= |
473 | inline void gp_Mat::Multiply (const Standard_Real theScalar) |
474 | { |
623e54f9 |
475 | myMat[0][0] *= theScalar; |
476 | myMat[0][1] *= theScalar; |
477 | myMat[0][2] *= theScalar; |
478 | myMat[1][0] *= theScalar; |
479 | myMat[1][1] *= theScalar; |
480 | myMat[1][2] *= theScalar; |
481 | myMat[2][0] *= theScalar; |
482 | myMat[2][1] *= theScalar; |
483 | myMat[2][2] *= theScalar; |
d5477f8c |
484 | } |
42cf5bc1 |
485 | |
d5477f8c |
486 | //======================================================================= |
487 | //function : Subtract |
488 | // purpose : |
489 | //======================================================================= |
490 | inline void gp_Mat::Subtract (const gp_Mat& theOther) |
491 | { |
623e54f9 |
492 | myMat[0][0] -= theOther.myMat[0][0]; |
493 | myMat[0][1] -= theOther.myMat[0][1]; |
494 | myMat[0][2] -= theOther.myMat[0][2]; |
495 | myMat[1][0] -= theOther.myMat[1][0]; |
496 | myMat[1][1] -= theOther.myMat[1][1]; |
497 | myMat[1][2] -= theOther.myMat[1][2]; |
498 | myMat[2][0] -= theOther.myMat[2][0]; |
499 | myMat[2][1] -= theOther.myMat[2][1]; |
500 | myMat[2][2] -= theOther.myMat[2][2]; |
d5477f8c |
501 | } |
42cf5bc1 |
502 | |
d5477f8c |
503 | //======================================================================= |
504 | //function : Subtracted |
505 | // purpose : |
506 | //======================================================================= |
507 | inline gp_Mat gp_Mat::Subtracted (const gp_Mat& theOther) const |
508 | { |
509 | gp_Mat aNewMat; |
623e54f9 |
510 | aNewMat.myMat[0][0] = myMat[0][0] - theOther.myMat[0][0]; |
511 | aNewMat.myMat[0][1] = myMat[0][1] - theOther.myMat[0][1]; |
512 | aNewMat.myMat[0][2] = myMat[0][2] - theOther.myMat[0][2]; |
513 | aNewMat.myMat[1][0] = myMat[1][0] - theOther.myMat[1][0]; |
514 | aNewMat.myMat[1][1] = myMat[1][1] - theOther.myMat[1][1]; |
515 | aNewMat.myMat[1][2] = myMat[1][2] - theOther.myMat[1][2]; |
516 | aNewMat.myMat[2][0] = myMat[2][0] - theOther.myMat[2][0]; |
517 | aNewMat.myMat[2][1] = myMat[2][1] - theOther.myMat[2][1]; |
518 | aNewMat.myMat[2][2] = myMat[2][2] - theOther.myMat[2][2]; |
d5477f8c |
519 | return aNewMat; |
520 | } |
42cf5bc1 |
521 | |
d5477f8c |
522 | //======================================================================= |
523 | //function : Transpose |
524 | // purpose : |
525 | //======================================================================= |
526 | // On macOS 10.13.6 with XCode 9.4.1 the compiler has a bug leading to |
527 | // generation of invalid code when method gp_Mat::Transpose() is called |
528 | // for a matrix which is when applied to vector; it looks like vector |
529 | // is transformed before the matrix is actually transposed; see #29978. |
530 | // To avoid this, we disable compiler optimization here. |
531 | #if defined(__APPLE__) && (__apple_build_version__ > 9020000) |
532 | __attribute__((optnone)) |
533 | #endif |
534 | inline void gp_Mat::Transpose() |
535 | { |
536 | Standard_Real aTemp; |
623e54f9 |
537 | aTemp = myMat[0][1]; |
538 | myMat[0][1] = myMat[1][0]; |
539 | myMat[1][0] = aTemp; |
540 | aTemp = myMat[0][2]; |
541 | myMat[0][2] = myMat[2][0]; |
542 | myMat[2][0] = aTemp; |
543 | aTemp = myMat[1][2]; |
544 | myMat[1][2] = myMat[2][1]; |
545 | myMat[2][1] = aTemp; |
d5477f8c |
546 | } |
42cf5bc1 |
547 | |
d5477f8c |
548 | //======================================================================= |
549 | //function : operator* |
550 | // purpose : |
551 | //======================================================================= |
552 | inline gp_Mat operator* (const Standard_Real theScalar, |
553 | const gp_Mat& theMat3D) |
554 | { |
555 | return theMat3D.Multiplied (theScalar); |
556 | } |
42cf5bc1 |
557 | |
558 | #endif // _gp_Mat_HeaderFile |