b311480e |
1 | // Copyright (c) 1995-1999 Matra Datavision |
973c2be1 |
2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
3 | // |
973c2be1 |
4 | // This file is part of Open CASCADE Technology software library. |
b311480e |
5 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
11 | // |
973c2be1 |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
b311480e |
14 | |
7fd59977 |
15 | // JCV 30/08/90 Modif passage version C++ 2.0 sur Sun |
16 | // JCV 1/10/90 Changement de nom du package vgeom -> gp |
17 | // JCV 4/10/90 codage sur la forme de la transformation shape,Scaling,negative |
18 | // JCV 10/12/90 Modif introduction des classes Mat et XYZ dans gp |
19 | |
20 | #define No_Standard_OutOfRange |
21 | |
42cf5bc1 |
22 | |
7fd59977 |
23 | #include <gp.hxx> |
42cf5bc1 |
24 | #include <gp_Ax1.hxx> |
25 | #include <gp_Ax2.hxx> |
26 | #include <gp_Ax3.hxx> |
27 | #include <gp_GTrsf.hxx> |
28 | #include <gp_Mat.hxx> |
29 | #include <gp_Pnt.hxx> |
30 | #include <gp_Quaternion.hxx> |
31 | #include <gp_Trsf.hxx> |
32 | #include <gp_Trsf2d.hxx> |
33 | #include <gp_Vec.hxx> |
34 | #include <gp_XYZ.hxx> |
7fd59977 |
35 | #include <Standard_ConstructionError.hxx> |
42cf5bc1 |
36 | #include <Standard_OutOfRange.hxx> |
bead40f2 |
37 | |
38 | //======================================================================= |
39 | //function : gp_Trsf |
40 | //purpose : Constructor from 2d |
41 | //======================================================================= |
bead40f2 |
42 | gp_Trsf::gp_Trsf (const gp_Trsf2d& T) : |
43 | scale(T.ScaleFactor()), |
44 | shape(T.Form()), |
45 | loc(T.TranslationPart().X(),T.TranslationPart().Y(), 0.0) |
46 | { |
47 | const gp_Mat2d& M = T.HVectorialPart(); |
48 | matrix(1,1) = M(1,1); |
49 | matrix(1,2) = M(1,2); |
50 | matrix(2,1) = M(2,1); |
51 | matrix(2,2) = M(2,2); |
52 | matrix(3,3) = 1.; |
53 | if (shape == gp_Ax1Mirror) |
54 | { |
55 | scale = 1; |
56 | matrix.Multiply(-1); |
57 | } |
58 | } |
59 | |
7fd59977 |
60 | //======================================================================= |
61 | //function : SetMirror |
62 | //purpose : |
63 | //======================================================================= |
64 | |
65 | void gp_Trsf::SetMirror (const gp_Ax1& A1) |
66 | { |
67 | shape = gp_Ax1Mirror; |
68 | scale = 1; |
69 | loc = A1.Location().XYZ(); |
70 | matrix.SetDot(A1.Direction().XYZ()); |
71 | matrix.Multiply(-2); |
72 | matrix.SetDiagonal (matrix.Value (1,1) + 1, |
73 | matrix.Value (2,2) + 1, |
74 | matrix.Value (3,3) + 1); |
75 | |
76 | loc.Multiply (matrix); |
77 | loc.Add (A1.Location().XYZ()); |
78 | matrix.Multiply(-1); |
79 | } |
80 | |
81 | //======================================================================= |
82 | //function : SetMirror |
83 | //purpose : |
84 | //======================================================================= |
85 | |
86 | void gp_Trsf::SetMirror (const gp_Ax2& A2) |
87 | { |
88 | shape = gp_Ax2Mirror; |
89 | scale = -1; |
90 | loc = A2.Location().XYZ(); |
91 | matrix.SetDot(A2.Direction().XYZ()); |
92 | matrix.Multiply(2); |
93 | matrix.SetDiagonal (matrix.Value (1,1) - 1, |
94 | matrix.Value (2,2) - 1, |
95 | matrix.Value (3,3) - 1); |
96 | |
97 | loc.Multiply (matrix); |
98 | loc.Add (A2.Location().XYZ()); |
99 | } |
100 | |
101 | //======================================================================= |
102 | //function : SetRotation |
103 | //purpose : |
104 | //======================================================================= |
105 | |
106 | void gp_Trsf::SetRotation (const gp_Ax1& A1, |
107 | const Standard_Real Ang) |
108 | { |
109 | shape = gp_Rotation; |
110 | scale = 1.; |
111 | loc = A1.Location().XYZ(); |
112 | matrix.SetRotation (A1.Direction().XYZ(), Ang); |
113 | loc.Reverse (); |
114 | loc.Multiply (matrix); |
115 | loc.Add (A1.Location().XYZ()); |
116 | } |
117 | |
118 | //======================================================================= |
119 | //function : SetRotation |
120 | //purpose : |
121 | //======================================================================= |
122 | |
123 | void gp_Trsf::SetRotation (const gp_Quaternion& R) |
124 | { |
125 | shape = gp_Rotation; |
126 | scale = 1.; |
127 | loc.SetCoord (0., 0., 0.); |
128 | matrix = R.GetMatrix(); |
129 | } |
130 | |
131 | //======================================================================= |
132 | //function : SetScale |
133 | //purpose : |
134 | //======================================================================= |
135 | |
136 | void gp_Trsf::SetScale (const gp_Pnt& P, const Standard_Real S) |
137 | { |
138 | shape = gp_Scale; |
139 | scale = S; |
140 | loc = P.XYZ(); |
141 | Standard_Real As = scale; |
142 | if (As < 0) As = - As; |
143 | Standard_ConstructionError_Raise_if |
144 | (As <= gp::Resolution(),"gp_Trsf::SetScaleFactor"); |
145 | matrix.SetIdentity (); |
146 | loc.Multiply (1-S); |
147 | } |
148 | |
149 | //======================================================================= |
150 | //function : SetTransformation |
151 | //purpose : |
152 | //======================================================================= |
153 | |
154 | void gp_Trsf::SetTransformation (const gp_Ax3& FromA1, |
155 | const gp_Ax3& ToA2) |
156 | { |
157 | shape = gp_CompoundTrsf; |
158 | scale = 1.0; |
159 | // matrix from XOY ToA2 : |
160 | matrix.SetCol (1, ToA2.XDirection().XYZ()); |
161 | matrix.SetCol (2, ToA2.YDirection().XYZ()); |
162 | matrix.SetCol (3, ToA2.Direction().XYZ()); |
163 | loc = ToA2.Location().XYZ(); |
164 | matrix.Transpose(); |
165 | loc.Multiply (matrix); |
166 | loc.Reverse (); |
167 | |
168 | // matrix FromA1 to XOY : |
169 | const gp_XYZ& xDir = FromA1.XDirection().XYZ(); |
170 | const gp_XYZ& yDir = FromA1.YDirection().XYZ(); |
171 | const gp_XYZ& zDir = FromA1.Direction().XYZ(); |
172 | |
173 | gp_Mat MA1 (xDir, yDir, zDir); |
174 | gp_XYZ MA1loc = FromA1.Location().XYZ(); |
175 | |
176 | // matrix * MA1 => FromA1 ToA2 : |
177 | MA1loc.Multiply (matrix); |
178 | loc.Add (MA1loc); |
179 | matrix.Multiply (MA1); |
180 | } |
181 | |
182 | void gp_Trsf::SetTransformation (const gp_Ax3& A3) |
183 | { |
184 | shape = gp_CompoundTrsf; |
185 | scale = 1.0; |
186 | loc = A3.Location().XYZ(); |
187 | matrix.SetCols (A3.XDirection().XYZ(), |
188 | A3.YDirection().XYZ(), |
189 | A3. Direction().XYZ()); |
190 | matrix.Transpose(); |
191 | loc.Multiply (matrix); |
192 | loc.Reverse (); |
193 | } |
194 | |
195 | //======================================================================= |
196 | //function : SetTransformation |
197 | //purpose : |
198 | //======================================================================= |
199 | |
200 | void gp_Trsf::SetTransformation (const gp_Quaternion& R, const gp_Vec& T) |
201 | { |
202 | shape = gp_CompoundTrsf; |
203 | scale = 1.; |
204 | loc = T.XYZ(); |
205 | matrix = R.GetMatrix(); |
206 | } |
207 | |
208 | //======================================================================= |
209 | //function : SetDisplacement |
210 | //purpose : |
211 | //======================================================================= |
212 | |
213 | void gp_Trsf::SetDisplacement (const gp_Ax3& FromA1, |
214 | const gp_Ax3& ToA2) |
215 | { |
216 | shape = gp_CompoundTrsf; |
217 | scale = 1.0; |
218 | // matrix from ToA2 to XOY : |
219 | matrix.SetCol (1, ToA2.XDirection().XYZ()); |
220 | matrix.SetCol (2, ToA2.YDirection().XYZ()); |
221 | matrix.SetCol (3, ToA2.Direction().XYZ()); |
222 | loc = ToA2.Location().XYZ(); |
223 | // matrix XOY to FromA1 : |
224 | const gp_XYZ& xDir = FromA1.XDirection().XYZ(); |
225 | const gp_XYZ& yDir = FromA1.YDirection().XYZ(); |
226 | const gp_XYZ& zDir = FromA1.Direction().XYZ(); |
227 | gp_Mat MA1 (xDir, yDir, zDir); |
228 | MA1.Transpose(); |
229 | gp_XYZ MA1loc = FromA1.Location().XYZ(); |
230 | MA1loc.Multiply (MA1); |
231 | MA1loc.Reverse(); |
232 | // matrix * MA1 |
233 | MA1loc.Multiply (matrix); |
234 | loc.Add (MA1loc); |
235 | matrix.Multiply (MA1); |
236 | } |
237 | |
238 | //======================================================================= |
239 | //function : SetTranslationPart |
240 | //purpose : |
241 | //======================================================================= |
242 | |
243 | void gp_Trsf::SetTranslationPart (const gp_Vec& V) { |
244 | |
245 | loc = V.XYZ(); |
57922171 |
246 | const Standard_Boolean locnull = (loc.SquareModulus() < gp::Resolution()); |
7fd59977 |
247 | |
248 | switch (shape) { |
249 | |
250 | case gp_Identity : |
251 | if (!locnull) shape = gp_Translation; |
252 | break; |
253 | |
254 | case gp_Translation : |
255 | if (locnull) shape = gp_Identity; |
256 | break; |
257 | |
258 | case gp_Rotation : |
259 | case gp_PntMirror : |
260 | case gp_Ax1Mirror : |
261 | case gp_Ax2Mirror : |
262 | case gp_Scale : |
263 | case gp_CompoundTrsf : |
264 | case gp_Other : |
57922171 |
265 | if (!locnull) { |
266 | shape = gp_CompoundTrsf; |
267 | } |
7fd59977 |
268 | break; |
269 | } |
270 | } |
271 | |
272 | //======================================================================= |
273 | //function : SetScaleFactor |
274 | //purpose : |
275 | //======================================================================= |
276 | |
277 | void gp_Trsf::SetScaleFactor (const Standard_Real S) |
278 | { |
279 | Standard_Real As = S; |
280 | if (As < 0) As = - As; |
281 | Standard_ConstructionError_Raise_if |
282 | (As <= gp::Resolution(),"gp_Trsf::SetScaleFactor"); |
283 | scale = S; |
284 | As = scale - 1.; |
285 | if (As < 0) As = - As; |
9256a43d |
286 | Standard_Boolean unit = As <= gp::Resolution(); // = (scale == 1) |
7fd59977 |
287 | As = scale + 1.; |
288 | if (As < 0) As = - As; |
9256a43d |
289 | Standard_Boolean munit = As <= gp::Resolution(); // = (scale == -1) |
7fd59977 |
290 | |
291 | switch (shape) { |
292 | case gp_Identity : |
293 | case gp_Translation : |
294 | if (!unit) shape = gp_Scale; |
295 | if (munit) shape = gp_PntMirror; |
296 | break; |
297 | case gp_Rotation : |
298 | if (!unit) shape = gp_CompoundTrsf; |
299 | break; |
300 | case gp_PntMirror : |
301 | case gp_Ax1Mirror : |
302 | case gp_Ax2Mirror : |
303 | if (!munit) shape = gp_Scale; |
304 | if (unit) shape = gp_Identity; |
305 | break; |
306 | case gp_Scale : |
307 | if (unit) shape = gp_Identity; |
308 | if (munit) shape = gp_PntMirror; |
309 | break; |
310 | case gp_CompoundTrsf : |
311 | break; |
312 | case gp_Other : |
313 | break; |
314 | } |
315 | } |
316 | |
317 | //======================================================================= |
318 | //function : SetValues |
319 | //purpose : |
320 | // 06-01-1998 modified by PMN : On utilise TolDist pour evaluer si les coeffs |
321 | // sont nuls : c'est toujours mieux que gp::Resolution ! |
322 | //======================================================================= |
323 | |
324 | void gp_Trsf::SetValues(const Standard_Real a11, |
325 | const Standard_Real a12, |
326 | const Standard_Real a13, |
327 | const Standard_Real a14, |
328 | const Standard_Real a21, |
329 | const Standard_Real a22, |
330 | const Standard_Real a23, |
331 | const Standard_Real a24, |
332 | const Standard_Real a31, |
333 | const Standard_Real a32, |
334 | const Standard_Real a33, |
7a8c6a36 |
335 | const Standard_Real a34) |
7fd59977 |
336 | { |
337 | gp_XYZ col1(a11,a21,a31); |
338 | gp_XYZ col2(a12,a22,a32); |
339 | gp_XYZ col3(a13,a23,a33); |
340 | gp_XYZ col4(a14,a24,a34); |
341 | // compute the determinant |
342 | gp_Mat M(col1,col2,col3); |
343 | Standard_Real s = M.Determinant(); |
344 | Standard_Real As = s; |
345 | if (As < 0) As = - As; |
346 | Standard_ConstructionError_Raise_if |
7a8c6a36 |
347 | (As < gp::Resolution(),"gp_Trsf::SetValues, null determinant"); |
7fd59977 |
348 | if (s > 0) |
349 | s = Pow(s,1./3.); |
350 | else |
351 | s = -Pow(-s,1./3.); |
352 | M.Divide(s); |
353 | |
7fd59977 |
354 | scale = s; |
355 | shape = gp_CompoundTrsf; |
7a8c6a36 |
356 | |
7fd59977 |
357 | matrix = M; |
7a8c6a36 |
358 | Orthogonalize(); |
359 | |
7fd59977 |
360 | loc = col4; |
361 | } |
362 | |
363 | //======================================================================= |
364 | //function : GetRotation |
365 | //purpose : |
366 | //======================================================================= |
367 | |
368 | gp_Quaternion gp_Trsf::GetRotation () const |
369 | { |
370 | return gp_Quaternion (matrix); |
371 | } |
372 | |
373 | //======================================================================= |
374 | //function : VectorialPart |
375 | //purpose : |
376 | //======================================================================= |
377 | |
378 | gp_Mat gp_Trsf::VectorialPart () const |
379 | { |
380 | if (scale == 1.0) return matrix; |
381 | gp_Mat M = matrix; |
382 | if (shape == gp_Scale || shape == gp_PntMirror) |
383 | M.SetDiagonal(scale*M.Value(1,1), |
384 | scale*M.Value(2,2), |
385 | scale*M.Value(3,3)); |
386 | else |
387 | M.Multiply (scale); |
388 | return M; |
389 | } |
390 | |
391 | //======================================================================= |
392 | //function : Invert |
393 | //purpose : |
394 | //======================================================================= |
395 | |
396 | void gp_Trsf::Invert() |
397 | { |
398 | // -1 |
399 | // X' = scale * R * X + T => X = (R / scale) * ( X' - T) |
400 | // |
401 | // Pour les gp_Trsf puisque le scale est extrait de la gp_Matrice R |
402 | // on a toujours determinant (R) = 1 et R-1 = R transposee. |
403 | if (shape == gp_Identity) { } |
404 | else if (shape == gp_Translation || shape == gp_PntMirror) loc.Reverse(); |
405 | else if (shape == gp_Scale) { |
406 | Standard_Real As = scale; |
407 | if (As < 0) As = - As; |
2d2b3d53 |
408 | Standard_ConstructionError_Raise_if (As <= gp::Resolution(), "gp_Trsf::Invert() - transformation has zero scale"); |
7fd59977 |
409 | scale = 1.0 / scale; |
410 | loc.Multiply (-scale); |
411 | } |
412 | else { |
413 | Standard_Real As = scale; |
414 | if (As < 0) As = - As; |
2d2b3d53 |
415 | Standard_ConstructionError_Raise_if (As <= gp::Resolution(), "gp_Trsf::Invert() - transformation has zero scale"); |
7fd59977 |
416 | scale = 1.0 / scale; |
417 | matrix.Transpose (); |
418 | loc.Multiply (matrix); |
419 | loc.Multiply (-scale); |
420 | } |
421 | } |
422 | |
423 | //======================================================================= |
424 | //function : Multiply |
425 | //purpose : |
426 | //======================================================================= |
427 | |
428 | void gp_Trsf::Multiply(const gp_Trsf& T) |
429 | { |
430 | if (T.shape == gp_Identity) { } |
431 | else if (shape == gp_Identity) { |
432 | shape = T.shape; |
433 | scale = T.scale; |
434 | loc = T.loc; |
435 | matrix = T.matrix; |
436 | } |
437 | else if (shape == gp_Rotation && T.shape == gp_Rotation) { |
f6f03db9 |
438 | if (T.loc.X() != 0.0 || T.loc.Y() != 0.0 || T.loc.Z() != 0.0) { |
7fd59977 |
439 | loc.Add (T.loc.Multiplied (matrix)); |
440 | } |
441 | matrix.Multiply(T.matrix); |
442 | } |
443 | else if (shape == gp_Translation && T.shape == gp_Translation) { |
444 | loc.Add (T.loc); |
445 | } |
446 | else if (shape == gp_Scale && T.shape == gp_Scale) { |
447 | loc.Add (T.loc.Multiplied(scale)); |
448 | scale = scale * T.scale; |
449 | } |
450 | else if (shape == gp_PntMirror && T.shape == gp_PntMirror) { |
451 | scale = 1.0; |
452 | shape = gp_Translation; |
453 | loc.Add (T.loc.Reversed()); |
454 | } |
455 | else if (shape == gp_Ax1Mirror && T.shape == gp_Ax1Mirror) { |
456 | shape = gp_Rotation; |
457 | loc.Add (T.loc.Multiplied (matrix)); |
458 | matrix.Multiply(T.matrix); |
459 | } |
460 | else if ((shape == gp_CompoundTrsf || shape == gp_Rotation || |
461 | shape == gp_Ax1Mirror || shape == gp_Ax2Mirror) |
462 | && T.shape == gp_Translation) { |
463 | gp_XYZ Tloc(T.loc); |
464 | Tloc.Multiply(matrix); |
465 | if (scale != 1.0) { Tloc.Multiply(scale); } |
466 | loc.Add (Tloc); |
467 | } |
468 | else if ((shape == gp_Scale || shape == gp_PntMirror) |
469 | && T.shape == gp_Translation) { |
470 | gp_XYZ Tloc(T.loc); |
471 | Tloc.Multiply (scale); |
472 | loc.Add (Tloc); |
473 | } |
474 | else if (shape == gp_Translation && |
475 | (T.shape == gp_CompoundTrsf || T.shape == gp_Rotation || |
476 | T.shape == gp_Ax1Mirror || T.shape == gp_Ax2Mirror)) { |
477 | shape = gp_CompoundTrsf; |
478 | scale = T.scale; |
479 | loc.Add (T.loc); |
480 | matrix = T.matrix; |
481 | } |
482 | else if (shape == gp_Translation && |
483 | (T.shape == gp_Scale || T.shape == gp_PntMirror)) { |
484 | shape = T.shape; |
485 | loc.Add (T.loc); |
486 | scale = T.scale; |
487 | } |
488 | else if ((shape == gp_PntMirror || shape == gp_Scale) && |
489 | (T.shape == gp_PntMirror || T.shape == gp_Scale)) { |
490 | shape = gp_CompoundTrsf; |
491 | gp_XYZ Tloc(T.loc); |
492 | Tloc.Multiply (scale); |
493 | loc.Add (Tloc); |
494 | scale = scale * T.scale; |
495 | } |
496 | else if ((shape == gp_CompoundTrsf || shape == gp_Rotation || |
497 | shape == gp_Ax1Mirror || shape == gp_Ax2Mirror) |
498 | && (T.shape == gp_Scale || T.shape == gp_PntMirror)) { |
499 | shape = gp_CompoundTrsf; |
500 | gp_XYZ Tloc(T.loc); |
501 | if (scale == 1.0) { |
502 | scale = T.scale; |
503 | Tloc.Multiply(matrix); |
504 | } |
505 | else { |
506 | Tloc.Multiply (matrix); |
507 | Tloc.Multiply (scale); |
508 | scale = scale * T.scale; |
509 | } |
510 | loc.Add (Tloc); |
511 | } |
512 | else if ((T.shape == gp_CompoundTrsf || T.shape == gp_Rotation || |
513 | T.shape == gp_Ax1Mirror || T.shape == gp_Ax2Mirror) |
514 | && (shape == gp_Scale || shape == gp_PntMirror)) { |
515 | shape = gp_CompoundTrsf; |
516 | gp_XYZ Tloc(T.loc); |
517 | Tloc.Multiply(scale); |
518 | loc.Add (Tloc); |
519 | scale = scale * T.scale; |
520 | matrix = T.matrix; |
521 | } |
522 | else { |
523 | shape = gp_CompoundTrsf; |
524 | gp_XYZ Tloc(T.loc); |
525 | Tloc.Multiply (matrix); |
526 | if (scale != 1.0) { |
527 | Tloc.Multiply (scale); |
528 | scale = scale * T.scale; |
529 | } |
530 | else { scale = T.scale; } |
531 | loc.Add (Tloc); |
532 | matrix.Multiply(T.matrix); |
533 | } |
534 | } |
535 | |
536 | //======================================================================= |
537 | //function : Power |
538 | //purpose : |
539 | //======================================================================= |
540 | |
541 | void gp_Trsf::Power (const Standard_Integer N) |
542 | { |
543 | if (shape == gp_Identity) { } |
544 | else { |
545 | if (N == 0) { |
546 | scale = 1.0; |
547 | shape = gp_Identity; |
548 | matrix.SetIdentity(); |
549 | loc = gp_XYZ (0.0, 0.0, 0.0); |
550 | } |
551 | else if (N == 1) { } |
552 | else if (N == -1) { Invert(); } |
553 | else { |
554 | if (N < 0) { Invert(); } |
555 | if (shape == gp_Translation) { |
556 | Standard_Integer Npower = N; |
557 | if (Npower < 0) Npower = - Npower; |
558 | Npower--; |
559 | gp_XYZ Temploc = loc; |
302f96fb |
560 | for(;;) { |
7fd59977 |
561 | if (IsOdd(Npower)) loc.Add (Temploc); |
562 | if (Npower == 1) break; |
563 | Temploc.Add (Temploc); |
564 | Npower = Npower/2; |
565 | } |
566 | } |
567 | else if (shape == gp_Scale) { |
568 | Standard_Integer Npower = N; |
569 | if (Npower < 0) Npower = - Npower; |
570 | Npower--; |
571 | gp_XYZ Temploc = loc; |
572 | Standard_Real Tempscale = scale; |
302f96fb |
573 | for(;;) { |
7fd59977 |
574 | if (IsOdd(Npower)) { |
575 | loc.Add (Temploc.Multiplied(scale)); |
576 | scale = scale * Tempscale; |
577 | } |
578 | if (Npower == 1) break; |
579 | Temploc.Add (Temploc.Multiplied(Tempscale)); |
580 | Tempscale = Tempscale * Tempscale; |
581 | Npower = Npower/2; |
582 | } |
583 | } |
584 | else if (shape == gp_Rotation) { |
585 | Standard_Integer Npower = N; |
586 | if (Npower < 0) Npower = - Npower; |
587 | Npower--; |
588 | gp_Mat Tempmatrix (matrix); |
589 | if (loc.X() == 0.0 && loc.Y() == 0.0 && loc.Z() == 0.0) { |
302f96fb |
590 | for(;;) { |
7fd59977 |
591 | if (IsOdd(Npower)) matrix.Multiply (Tempmatrix); |
592 | if (Npower == 1) break; |
593 | Tempmatrix.Multiply (Tempmatrix); |
594 | Npower = Npower/2; |
595 | } |
596 | } |
597 | else { |
598 | gp_XYZ Temploc = loc; |
302f96fb |
599 | for(;;) { |
7fd59977 |
600 | if (IsOdd(Npower)) { |
601 | loc.Add (Temploc.Multiplied (matrix)); |
602 | matrix.Multiply (Tempmatrix); |
603 | } |
604 | if (Npower == 1) break; |
605 | Temploc.Add (Temploc.Multiplied (Tempmatrix)); |
606 | Tempmatrix.Multiply (Tempmatrix); |
607 | Npower = Npower/2; |
608 | } |
609 | } |
610 | } |
611 | else if (shape == gp_PntMirror || shape == gp_Ax1Mirror || |
612 | shape == gp_Ax2Mirror) { |
613 | if (IsEven (N)) { |
614 | shape = gp_Identity; |
615 | scale = 1.0; |
616 | matrix.SetIdentity (); |
617 | loc.SetX(0); |
618 | loc.SetY(0); |
619 | loc.SetZ(0); |
620 | } |
621 | } |
622 | else { |
623 | shape = gp_CompoundTrsf; |
624 | Standard_Integer Npower = N; |
625 | if (Npower < 0) Npower = - Npower; |
626 | Npower--; |
627 | gp_XYZ Temploc = loc; |
628 | Standard_Real Tempscale = scale; |
629 | gp_Mat Tempmatrix (matrix); |
302f96fb |
630 | for(;;) { |
7fd59977 |
631 | if (IsOdd(Npower)) { |
632 | loc.Add ((Temploc.Multiplied (matrix)).Multiplied (scale)); |
633 | scale = scale * Tempscale; |
634 | matrix.Multiply (Tempmatrix); |
635 | } |
636 | if (Npower == 1) break; |
637 | Tempscale = Tempscale * Tempscale; |
638 | Temploc.Add ( (Temploc.Multiplied (Tempmatrix)).Multiplied |
639 | (Tempscale) |
640 | ); |
641 | Tempmatrix.Multiply (Tempmatrix); |
642 | Npower = Npower/2; |
643 | } |
644 | } |
645 | } |
646 | } |
647 | } |
648 | |
649 | //======================================================================= |
650 | //function : PreMultiply |
651 | //purpose : |
652 | //======================================================================= |
653 | |
654 | void gp_Trsf::PreMultiply (const gp_Trsf& T) |
655 | { |
656 | if (T.shape == gp_Identity) { } |
657 | else if (shape == gp_Identity) { |
658 | shape = T.shape; |
659 | scale = T.scale; |
660 | loc = T.loc; |
661 | matrix = T.matrix; |
662 | } |
663 | else if (shape == gp_Rotation && T.shape == gp_Rotation) { |
664 | loc.Multiply (T.matrix); |
665 | loc.Add (T.loc); |
666 | matrix.PreMultiply(T.matrix); |
667 | } |
668 | else if (shape == gp_Translation && T.shape == gp_Translation) { |
669 | loc.Add (T.loc); |
670 | } |
671 | else if (shape == gp_Scale && T.shape == gp_Scale) { |
672 | loc.Multiply (T.scale); |
673 | loc.Add (T.loc); |
674 | scale = scale * T.scale; |
675 | } |
676 | else if (shape == gp_PntMirror && T.shape == gp_PntMirror) { |
677 | scale = 1.0; |
678 | shape = gp_Translation; |
679 | loc.Reverse(); |
680 | loc.Add (T.loc); |
681 | } |
682 | else if (shape == gp_Ax1Mirror && T.shape == gp_Ax1Mirror) { |
683 | shape = gp_Rotation; |
684 | loc.Multiply (T.matrix); |
685 | loc.Add (T.loc); |
686 | matrix.PreMultiply(T.matrix); |
687 | } |
688 | else if ((shape == gp_CompoundTrsf || shape == gp_Rotation || |
689 | shape == gp_Ax1Mirror || shape == gp_Ax2Mirror) |
690 | && T.shape == gp_Translation) { |
691 | loc.Add (T.loc); |
692 | } |
693 | else if ((shape == gp_Scale || shape == gp_PntMirror) |
694 | && T.shape == gp_Translation) { |
695 | loc.Add (T.loc); |
696 | } |
697 | else if (shape == gp_Translation && |
698 | (T.shape == gp_CompoundTrsf || T.shape == gp_Rotation |
699 | || T.shape == gp_Ax1Mirror || T.shape == gp_Ax2Mirror)) { |
700 | shape = gp_CompoundTrsf; |
701 | matrix = T.matrix; |
702 | if (T.scale == 1.0) loc.Multiply (T.matrix); |
703 | else { |
704 | scale = T.scale; |
705 | loc.Multiply (matrix); |
706 | loc.Multiply (scale); |
707 | } |
708 | loc.Add (T.loc); |
709 | } |
710 | else if ((T.shape == gp_Scale || T.shape == gp_PntMirror) |
711 | && shape == gp_Translation) { |
712 | loc.Multiply (T.scale); |
713 | loc.Add (T.loc); |
714 | scale = T.scale; |
715 | shape = T.shape; |
716 | } |
717 | else if ((shape == gp_PntMirror || shape == gp_Scale) && |
718 | (T.shape == gp_PntMirror || T.shape == gp_Scale)) { |
719 | shape = gp_CompoundTrsf; |
720 | loc.Multiply (T.scale); |
721 | loc.Add (T.loc); |
722 | scale = scale * T.scale; |
723 | } |
724 | else if ((shape == gp_CompoundTrsf || shape == gp_Rotation || |
725 | shape == gp_Ax1Mirror || shape == gp_Ax2Mirror) |
726 | && (T.shape == gp_Scale || T.shape == gp_PntMirror)) { |
727 | shape = gp_CompoundTrsf; |
728 | loc.Multiply (T.scale); |
729 | loc.Add (T.loc); |
730 | scale = scale * T.scale; |
731 | } |
732 | else if ((T.shape == gp_CompoundTrsf || T.shape == gp_Rotation || |
733 | T.shape == gp_Ax1Mirror || T.shape == gp_Ax2Mirror) |
734 | && (shape == gp_Scale || shape == gp_PntMirror)) { |
735 | shape = gp_CompoundTrsf; |
736 | matrix = T.matrix; |
737 | if (T.scale == 1.0) loc.Multiply (T.matrix); |
738 | else { |
739 | loc.Multiply (matrix); |
740 | loc.Multiply (T.scale); |
741 | scale = T.scale * scale; |
742 | } |
743 | loc.Add (T.loc); |
744 | } |
745 | else { |
746 | shape = gp_CompoundTrsf; |
747 | loc.Multiply (T.matrix); |
748 | if (T.scale != 1.0) { |
749 | loc.Multiply (T.scale); scale = scale * T.scale; |
750 | } |
751 | loc.Add (T.loc); |
752 | matrix.PreMultiply(T.matrix); |
753 | } |
754 | } |
755 | |
756 | //======================================================================= |
757 | //function : GetRotation |
758 | //purpose : algorithm from A.Korn, M.Korn, "Mathematical Handbook for |
759 | // scientists and Engineers" McGraw-Hill, 1961, ch.14.10-2. |
760 | //======================================================================= |
761 | |
762 | Standard_Boolean gp_Trsf::GetRotation (gp_XYZ& theAxis, |
763 | Standard_Real& theAngle) const |
764 | { |
765 | gp_Quaternion Q = GetRotation(); |
766 | gp_Vec aVec; |
767 | Q.GetVectorAndAngle (aVec, theAngle); |
768 | theAxis = aVec.XYZ(); |
769 | return Standard_True; |
770 | } |
7a8c6a36 |
771 | |
772 | //======================================================================= |
773 | //function : Orthogonalize |
774 | //purpose : |
4dba155d |
775 | //ATTENTION!!! |
776 | // Orthogonalization is not equivalent transformation. Therefore, |
777 | // transformation with source matrix and with orthogonalized matrix can |
778 | // lead to different results for one shape. Consequently, source matrix must |
779 | // be close to orthogonalized matrix for reducing these differences. |
7a8c6a36 |
780 | //======================================================================= |
781 | void gp_Trsf::Orthogonalize() |
782 | { |
4dba155d |
783 | //Matrix M is called orthogonal if and only if |
784 | // M*Transpose(M) == E |
785 | //where E is identity matrix. |
786 | |
787 | //Set of all rows (as of all columns) of matrix M (for gp_Trsf class) is |
788 | //orthonormal basis. If this condition is not satisfied then the basis can be |
789 | //orthonormalized in accordance with below described algorithm. |
790 | |
791 | //In 3D-space, we have the linear span of three basis vectors: V1, V2 and V3. |
792 | //Correspond orthonormalized basis is formed by vectors Vn1, Vn2 and Vn3. |
793 | |
794 | //In this case, |
795 | // Vn_{i}*Vn_{j} = (i == j)? 1 : 0. |
796 | |
797 | //The algorithm includes following steps: |
798 | |
799 | //1. Normalize V1 vector: |
800 | // V1n=V1/|V1|; |
801 | // |
802 | //2. Let |
803 | // V2n=V2-m*V1n. |
804 | // |
805 | //After multiplication two parts of this equation by V1n, |
806 | //we will have following equation: |
807 | // 0=V2*V1n-m <==> m=V2*V1n. |
808 | // |
809 | //Consequently, |
810 | // V2n=V2-(V2*V1n)*V1n. |
811 | |
812 | //3. Let |
813 | // V3n=V3-m1*V1n-m2*V2n. |
814 | // |
815 | //After multiplication two parts of this equation by V1n, |
816 | //we will have following equation: |
817 | // 0=V3*V1n-m1 <==> m1=V3*V1n. |
818 | // |
819 | //After multiplication two parts of main equation by V2n, |
820 | //we will have following equation: |
821 | // 0=V3*V2n-m2 <==> m2=V3*V2n. |
822 | // |
823 | //In conclusion, |
824 | // V3n=V3-(V3*V1n)*V1n-(V3*V2n)*V2n. |
825 | |
7a8c6a36 |
826 | gp_Mat aTM(matrix); |
827 | |
828 | gp_XYZ aV1 = aTM.Column(1); |
829 | gp_XYZ aV2 = aTM.Column(2); |
830 | gp_XYZ aV3 = aTM.Column(3); |
831 | |
832 | aV1.Normalize(); |
833 | |
834 | aV2 -= aV1*(aV2.Dot(aV1)); |
835 | aV2.Normalize(); |
836 | |
837 | aV3 -= aV1*(aV3.Dot(aV1)) + aV2*(aV3.Dot(aV2)); |
838 | aV3.Normalize(); |
839 | |
840 | aTM.SetCols(aV1, aV2, aV3); |
841 | |
842 | aV1 = aTM.Row(1); |
843 | aV2 = aTM.Row(2); |
844 | aV3 = aTM.Row(3); |
845 | |
846 | aV1.Normalize(); |
847 | |
848 | aV2 -= aV1*(aV2.Dot(aV1)); |
849 | aV2.Normalize(); |
850 | |
851 | aV3 -= aV1*(aV3.Dot(aV1)) + aV2*(aV3.Dot(aV2)); |
852 | aV3.Normalize(); |
853 | |
854 | aTM.SetRows(aV1, aV2, aV3); |
855 | |
856 | matrix = aTM; |
857 | } |