82223a3cdf5fe7f25d3a8987a2be7d2144142558
[occt.git] / src / gp / gp_Trsf2d.cxx
1 // File gp_Ax2d.cxx, JCV 06/90 
2 // File gp_Trsf.cxx,  REG 03/06/90 nouvelle version
3 // JCV 08/01/91 Modif introduction des classes Mat2d et XY dans gp
4
5 #define No_Standard_OutOfRange
6
7 #include <gp_Trsf2d.ixx>
8 #include <gp.hxx>
9 #include <Standard_ConstructionError.hxx>
10
11 void gp_Trsf2d::SetMirror (const gp_Ax2d& A)
12 {
13   shape = gp_Ax1Mirror;
14   scale = - 1.0;
15   const gp_Dir2d& V = A.Direction ();
16   const gp_Pnt2d& P = A.Location ();
17   Standard_Real VX = V.X();
18   Standard_Real VY = V.Y();
19   Standard_Real X0 = P.X();
20   Standard_Real Y0 = P.Y();
21   matrix.SetCol (1, gp_XY (1.0 - 2.0 * VX * VX, -2.0 * VX * VY));
22   matrix.SetCol (2, gp_XY (-2.0 * VX * VY, 1.0 - 2.0 * VY * VY));
23
24   loc.SetCoord  (-2.0 * ((VX * VX - 1.0) * X0 + (VX * VY * Y0)),
25                  -2.0 * ((VX * VY * X0) + (VY * VY - 1.0) * Y0));
26 }
27
28 void gp_Trsf2d::SetTransformation (const gp_Ax2d& FromA1,
29                                    const gp_Ax2d& ToA2)
30 {
31   shape = gp_CompoundTrsf;
32   scale = 1.0;
33   //matrix from XOY to A2 :
34   const gp_XY& V1 = ToA2.Direction().XY();
35   gp_XY V2 (-V1.Y(), V1.X());
36   matrix.SetCol (1, V1);
37   matrix.SetCol (2, V2);
38   loc = ToA2.Location().XY();
39   matrix.Transpose();
40   loc.Multiply (matrix);
41   loc.Reverse();
42   //matrix FromA1 to XOY
43   const gp_XY& V3 = FromA1.Direction().XY();
44   gp_XY V4 (-V3.Y(), V3.X());
45   gp_Mat2d MA1 (V3, V4);
46   gp_XY MA1loc = FromA1.Location().XY();
47   //matrix * MA1 => FromA1 ToA2
48   MA1loc.Multiply (matrix);
49   loc.Add (MA1loc);
50   matrix.Multiply (MA1);
51 }
52
53 void gp_Trsf2d::SetTransformation (const gp_Ax2d& A)
54 {
55   shape = gp_CompoundTrsf;
56   scale = 1.0;
57   const gp_XY& V1 = A.Direction().XY();
58   gp_XY V2 (-V1.Y(), V1.X());
59   matrix.SetCol (1, V1);
60   matrix.SetCol (2, V2);
61   loc = A.Location().XY();
62   matrix.Transpose();
63   loc.Multiply (matrix);
64   loc.Reverse();
65 }
66
67 void gp_Trsf2d::SetTranslationPart (const gp_Vec2d& V)
68 {   
69   loc = V.XY();
70   Standard_Real X = loc.X();
71   if (X < 0) X = - X;
72   Standard_Real Y = loc.Y();
73   if (Y < 0) Y = - Y;
74   if (X <= gp::Resolution() && Y <= gp::Resolution()) {
75     if (shape == gp_Identity  || shape == gp_PntMirror ||
76         shape == gp_Scale     || shape == gp_Rotation  ||
77         shape == gp_Ax1Mirror ) { }
78     else if (shape == gp_Translation) { shape = gp_Identity; }
79     else { shape = gp_CompoundTrsf; }
80   }
81   else {
82     if (shape == gp_Translation || shape == gp_Scale ||
83         shape == gp_PntMirror) { }
84     else if (shape == gp_Identity) { shape = gp_Translation; }
85     else { shape = gp_CompoundTrsf; }
86   }
87 }
88
89 void gp_Trsf2d::SetScaleFactor (const Standard_Real S)
90 {   
91   if (S == 1.0) {
92     Standard_Real X = loc.X();
93     if (X < 0) X = - X;
94     Standard_Real Y = loc.Y();
95     if (Y < 0) Y = - Y;
96     if (X <= gp::Resolution() && Y <= gp::Resolution()) {
97       if (shape == gp_Identity || shape == gp_Rotation) { }
98       else if (shape == gp_Scale)  { shape = gp_Identity; }
99       else if (shape == gp_PntMirror) { shape = gp_Translation; }
100       else { shape = gp_CompoundTrsf; }
101     }
102     else {
103       if (shape == gp_Identity || shape == gp_Rotation ||
104           shape == gp_Scale)  { }
105       else if (shape == gp_PntMirror) { shape = gp_Translation; }
106       else { shape = gp_CompoundTrsf; }
107     }
108   }
109   else if (S == -1) {
110     if (shape == gp_PntMirror || shape == gp_Ax1Mirror) { }
111     else if (shape == gp_Identity || shape == gp_Scale) { 
112       shape = gp_PntMirror;
113     }
114     else { shape = gp_CompoundTrsf; }
115   }
116   else {
117     if (shape == gp_Scale) { }
118     else if (shape == gp_Identity || shape == gp_Translation ||
119              shape == gp_PntMirror) { shape = gp_Scale; }
120     else { shape = gp_CompoundTrsf; }
121   }
122   scale = S;
123 }
124
125 gp_Mat2d gp_Trsf2d::VectorialPart () const
126
127   if (scale == 1.0)  return matrix;
128   gp_Mat2d M = matrix;
129   if (shape == gp_Scale || shape == gp_PntMirror)
130     M.SetDiagonal (matrix.Value(1,1) * scale, matrix.Value(2,2) * scale);
131   else
132     M.Multiply (scale);
133   return M;
134 }
135
136 Standard_Real gp_Trsf2d::RotationPart () const
137
138   return ATan2 ( matrix.Value(2,1), matrix.Value(1,1) );
139 }
140
141 void gp_Trsf2d::Invert()
142
143   //                                    -1
144   //  X' = scale * R * X + T  =>  X = (R  / scale)  * ( X' - T)
145   //
146   // Pour les gp_Trsf2d puisque le scale est extrait de la matrice R
147   // on a toujours determinant (R) = 1 et R-1 = R transposee.
148   if (shape == gp_Identity) { }
149   else if ( shape == gp_Translation || shape == gp_PntMirror) { 
150     loc.Reverse(); 
151   }
152   else if ( shape == gp_Scale) {
153     Standard_Real As = scale;
154     if (As < 0) As = - As;
155     Standard_ConstructionError_Raise_if(As <= gp::Resolution(),""); 
156     scale = 1.0 / scale;
157     loc.Multiply (-scale);
158   }
159   else {
160     Standard_Real As = scale;
161     if (As < 0) As = - As;
162     Standard_ConstructionError_Raise_if(As <= gp::Resolution(),""); 
163     scale = 1.0 / scale;
164     matrix.Transpose();
165     loc.Multiply (matrix);
166     loc.Multiply (-scale);
167   }
168 }
169
170 void gp_Trsf2d::Multiply(const gp_Trsf2d& T)
171 {
172   if (T.shape == gp_Identity) { }
173   else if (shape == gp_Identity) {
174     shape = T.shape;
175     scale = T.scale;
176     loc = T.loc;
177     matrix = T.matrix;
178   } 
179   else if (shape == gp_Rotation && T.shape == gp_Rotation) { 
180     if (loc.X() != 0.0 || loc.Y() != 0.0) {
181       loc.Add (T.loc.Multiplied (matrix));
182     }
183     matrix.Multiply(T.matrix);
184   }
185   else if (shape == gp_Translation && T.shape == gp_Translation) {
186     loc.Add (T.loc);
187   }
188   else if (shape == gp_Scale && T.shape == gp_Scale) {
189     loc.Add (T.loc.Multiplied(scale));
190     scale = scale * T.scale;
191   }
192   else if (shape == gp_PntMirror && T.shape == gp_PntMirror) {
193     scale = 1.0;
194     shape = gp_Translation;
195     loc.Add (T.loc.Reversed());
196   }
197   else if (shape == gp_Ax1Mirror && T.shape == gp_Ax1Mirror) {
198     shape = gp_Rotation;
199     loc.Add (T.loc.Multiplied (matrix));
200     matrix.Multiply(T.matrix);
201   }
202   else if ((shape == gp_CompoundTrsf || shape == gp_Rotation ||
203             shape == gp_Ax1Mirror) && T.shape == gp_Translation) {
204     gp_XY Tloc (T.loc);
205     Tloc.Multiply (matrix);
206     if (scale != 1.0) Tloc.Multiply (scale);
207     loc.Add (Tloc);
208   }
209   else if ((shape == gp_Scale || shape == gp_PntMirror)
210            && T.shape == gp_Translation) {
211     gp_XY Tloc (T.loc);
212     Tloc.Multiply (scale);
213     loc.Add (Tloc);
214   }
215   else if (shape == gp_Translation &&
216            (T.shape == gp_CompoundTrsf ||
217             T.shape == gp_Rotation || T.shape == gp_Ax1Mirror)) {
218     shape = gp_CompoundTrsf;
219     scale = T.scale;
220     loc.Add (T.loc);
221     matrix = T.matrix;
222   }
223   else if (shape == gp_Translation && 
224            (T.shape == gp_Scale || T.shape == gp_PntMirror)) {
225     shape = T.shape;
226     loc.Add (T.loc);
227     scale = T.scale;
228   }
229   else if ((shape == gp_PntMirror || shape == gp_Scale) &&
230            (T.shape == gp_PntMirror || T.shape == gp_Scale)) {
231     shape = gp_CompoundTrsf;
232     gp_XY Tloc (T.loc);
233     Tloc.Multiply (scale);
234     loc.Add (Tloc);
235     scale = scale * T.scale;
236   }
237   else if ((shape == gp_CompoundTrsf || shape == gp_Rotation ||
238             shape == gp_Ax1Mirror)
239            && (T.shape == gp_Scale || T.shape == gp_PntMirror)) {
240     shape = gp_CompoundTrsf;
241     gp_XY Tloc (T.loc);
242     Tloc.Multiply(matrix);
243     if (scale == 1.0)  scale = T.scale;
244     else {
245       Tloc.Multiply (scale);
246       scale = scale * T.scale;
247     }
248     loc.Add (Tloc);
249   }
250   else if ((T.shape == gp_CompoundTrsf || T.shape == gp_Rotation ||
251             T.shape == gp_Ax1Mirror)
252            && (shape == gp_Scale || shape == gp_PntMirror)) {
253     shape = gp_CompoundTrsf;
254     gp_XY Tloc (T.loc);
255     Tloc.Multiply (scale);
256     scale = scale * T.scale;
257     loc.Add (Tloc);
258     matrix = T.matrix;
259   }
260   else {
261     shape = gp_CompoundTrsf;
262     gp_XY Tloc (T.loc);
263     Tloc.Multiply (matrix);
264     if (scale != 1.0) {
265       Tloc.Multiply (scale);
266       scale = scale * T.scale;
267     }
268     else { scale = T.scale; }
269     loc.Add (Tloc);
270     matrix.Multiply (T.matrix);
271   }
272 }
273
274 void gp_Trsf2d::Power (const Standard_Integer N)
275 {
276   if (shape == gp_Identity) { }
277   else {
278     if (N == 0)  {
279       scale = 1.0;
280       shape = gp_Identity;
281       matrix.SetIdentity();
282       loc = gp_XY (0.0, 0.0);
283     }
284     else if (N == 1)  { }
285     else if (N == -1) Invert();
286     else {
287       if (N < 0) Invert();
288       if (shape == gp_Translation) { 
289         Standard_Integer Npower = N;
290         if (Npower < 0) Npower = - Npower;
291         Npower--;
292         gp_XY Temploc = loc;
293         while (1) {
294           if (IsOdd(Npower))  loc.Add (Temploc);
295           if (Npower == 1) break;
296           Temploc.Add (Temploc);
297           Npower = Npower/2;
298         }
299       }
300       else if (shape == gp_Scale) {
301         Standard_Integer Npower = N;
302         if (Npower < 0) Npower = - Npower;
303         Npower--;
304         gp_XY Temploc = loc;
305         Standard_Real Tempscale = scale;
306         while (1) {
307           if (IsOdd(Npower)) {
308             loc.Add (Temploc.Multiplied(scale));
309             scale = scale * Tempscale;
310           }
311           if (Npower == 1) break;
312           Temploc.Add (Temploc.Multiplied(Tempscale));
313           Tempscale = Tempscale * Tempscale;
314           Npower = Npower/2;
315         }
316       }
317       else if (shape == gp_Rotation) {
318         Standard_Integer Npower = N;
319         if (Npower < 0) Npower = - Npower;
320         Npower--;
321         gp_Mat2d Tempmatrix (matrix);
322         if (loc.X() == 0.0 && loc.Y() == 0.0) {
323           while (1) {
324             if (IsOdd(Npower))  matrix.Multiply (Tempmatrix);
325             if (Npower == 1) break;
326             Tempmatrix.Multiply (Tempmatrix);
327             Npower = Npower/2;
328           }
329         }
330         else {
331           gp_XY Temploc = loc;
332           while (1) {
333             if (IsOdd(Npower)) {
334               loc.Add (Temploc.Multiplied (matrix));
335               matrix.Multiply (Tempmatrix);
336             }
337             if (Npower == 1) break;
338             Temploc.Add (Temploc.Multiplied (Tempmatrix));
339             Tempmatrix.Multiply (Tempmatrix);
340             Npower = Npower/2;
341           }
342         }
343       }
344       else if (shape == gp_PntMirror || shape == gp_Ax1Mirror) {
345         if (IsEven (N)) {
346           shape = gp_Identity;
347           scale = 1.0;
348           matrix.SetIdentity ();
349           loc.SetCoord (0.0, 0.0);
350         }
351       }
352       else {
353         shape = gp_CompoundTrsf;
354         Standard_Integer Npower = N;
355         if (Npower < 0) Npower = - Npower;
356         Npower--;
357         matrix.SetDiagonal (scale*matrix.Value(1,1),
358                             scale*matrix.Value(2,2));
359         gp_XY Temploc = loc;
360         Standard_Real Tempscale = scale;
361         gp_Mat2d Tempmatrix (matrix);
362         while (1) {
363           if (IsOdd(Npower)) {
364             loc.Add ((Temploc.Multiplied (matrix)).Multiplied (scale));
365             scale = scale * Tempscale;
366             matrix.Multiply (Tempmatrix);
367           }
368           if (Npower == 1) break;
369           Tempscale = Tempscale * Tempscale;
370           Temploc.Add ( (Temploc.Multiplied (Tempmatrix)).Multiplied 
371                        (Tempscale)
372                        );
373           Tempmatrix.Multiply (Tempmatrix);
374           Npower = Npower/2;
375         }
376       }
377     }
378   }
379 }
380
381 void gp_Trsf2d::PreMultiply (const gp_Trsf2d& T)
382 {
383   if (T.shape == gp_Identity) { }
384   else if (shape == gp_Identity) {
385     shape = T.shape;
386     scale = T.scale;
387     loc = T.loc;
388     matrix = T.matrix;
389   } 
390   else if (shape == gp_Rotation && T.shape == gp_Rotation) { 
391     loc.Multiply (T.matrix);
392     loc.Add (T.loc);
393     matrix.PreMultiply(T.matrix);
394   }
395   else if (shape == gp_Translation && T.shape == gp_Translation) {
396     loc.Add (T.loc);
397   }
398   else if (shape == gp_Scale && T.shape == gp_Scale) {
399     loc.Multiply (T.scale);
400     loc.Add (T.loc);
401     scale = scale * T.scale;
402   }
403   else if (shape == gp_PntMirror && T.shape == gp_PntMirror) {
404     scale = 1.0;
405     shape = gp_Translation;
406     loc.Reverse();
407     loc.Add (T.loc);
408   }
409   else if (shape == gp_Ax1Mirror && T.shape == gp_Ax1Mirror) {
410     shape = gp_Rotation;
411     loc.Multiply (T.matrix);
412     loc.Add (T.loc);
413     matrix.PreMultiply(T.matrix);
414   }
415   else if ((shape == gp_CompoundTrsf || shape == gp_Rotation ||
416             shape == gp_Ax1Mirror) && T.shape == gp_Translation) {
417     loc.Add (T.loc);
418   }
419   else if ((shape == gp_Scale || shape == gp_PntMirror)
420            && T.shape == gp_Translation) {
421     loc.Add (T.loc);
422   }
423   else if (shape == gp_Translation &&
424            (T.shape == gp_CompoundTrsf ||
425             T.shape == gp_Rotation || T.shape == gp_Ax1Mirror)) {
426     shape = gp_CompoundTrsf;
427     matrix = T.matrix;
428     if (T.scale == 1.0)  loc.Multiply (T.matrix);
429     else {
430       scale = T.scale;
431       loc.Multiply (matrix);
432       loc.Multiply (scale);
433     }
434     loc.Add (T.loc);
435   }
436   else if ((T.shape == gp_Scale || T.shape == gp_PntMirror)
437            && shape == gp_Translation) {
438     loc.Multiply (T.scale);
439     loc.Add (T.loc);
440     scale = T.scale;
441     shape = T.shape;
442   }
443   else if ((shape == gp_PntMirror || shape == gp_Scale) &&
444            (T.shape == gp_PntMirror || T.shape == gp_Scale)) {
445     shape = gp_CompoundTrsf;
446     loc.Multiply (T.scale);
447     loc.Add (T.loc);
448     scale = scale * T.scale;
449   }
450   else if ((shape == gp_CompoundTrsf || shape == gp_Rotation ||
451             shape == gp_Ax1Mirror)
452            && (T.shape == gp_Scale || T.shape == gp_PntMirror)) {
453     shape = gp_CompoundTrsf;
454     loc.Multiply (T.scale);
455     loc.Add (T.loc);
456     scale = scale * T.scale;
457   } 
458   else if ((T.shape == gp_CompoundTrsf || T.shape == gp_Rotation ||
459             T.shape == gp_Ax1Mirror) 
460            && (shape == gp_Scale || shape == gp_PntMirror)) {
461     shape = gp_CompoundTrsf;
462     matrix = T.matrix;
463     if (T.scale == 1.0)  loc.Multiply (T.matrix);
464     else {
465       loc.Multiply (matrix);
466       loc.Multiply (T.scale);
467       scale = T.scale * scale;
468     }
469     loc.Add (T.loc);
470   } 
471   else {
472     shape = gp_CompoundTrsf;
473     loc.Multiply (T.matrix);
474     if (T.scale != 1.0) {
475       loc.Multiply(T.scale);   scale = scale * T.scale;
476     }
477     loc.Add (T.loc);
478     matrix.PreMultiply(T.matrix);
479   }
480 }
481