0026377: Passing Handle objects as arguments to functions as non-const reference...
[occt.git] / src / gp / gp_Dir2d.cxx
1 // Copyright (c) 1995-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 // JCV 08/01/90 Modifs suite a l'introduction des classes XY et Mat2d dans gp
16
17 #include <gp_Ax2d.hxx>
18 #include <gp_Dir2d.hxx>
19 #include <gp_Trsf2d.hxx>
20 #include <gp_Vec2d.hxx>
21 #include <gp_XY.hxx>
22 #include <Standard_ConstructionError.hxx>
23 #include <Standard_DomainError.hxx>
24 #include <Standard_OutOfRange.hxx>
25
26 Standard_Real gp_Dir2d::Angle (const gp_Dir2d& Other) const
27 {
28   //    Commentaires :
29   //    Au dessus de 45 degres l'arccos donne la meilleur precision pour le
30   //    calcul de l'angle. Sinon il vaut mieux utiliser l'arcsin.
31   //    Les erreurs commises sont loin d'etre negligeables lorsque l'on est
32   //    proche de zero ou de 90 degres.
33   //    En 2D les valeurs angulaires sont comprises entre -PI et PI
34   Standard_Real Cosinus = coord.Dot   (Other.coord);
35   Standard_Real Sinus = coord.Crossed (Other.coord);
36   if (Cosinus > -0.70710678118655 && Cosinus < 0.70710678118655) { 
37     if (Sinus > 0.0) return   acos (Cosinus);
38     else             return - acos (Cosinus);
39   }
40   else {
41     if (Cosinus > 0.0)  return      asin (Sinus);
42     else { 
43       if (Sinus > 0.0) return  M_PI - asin (Sinus);
44       else             return -M_PI - asin (Sinus);
45     }
46   }
47 }
48
49 void gp_Dir2d::Mirror (const gp_Ax2d& A2)
50 {
51   const gp_XY& XY = A2.Direction().XY();
52   Standard_Real A = XY.X();
53   Standard_Real B = XY.Y();
54   Standard_Real X = coord.X();
55   Standard_Real Y = coord.Y();
56   Standard_Real M1 = 2.0 * A * B;
57   Standard_Real XX = ((2.0 * A * A) - 1.0) * X + M1 * Y;
58   Standard_Real YY = M1 * X + ((2.0 * B * B) - 1.0) * Y;
59   coord.SetCoord(XX,YY);
60 }
61
62 void gp_Dir2d::Transform (const gp_Trsf2d& T)
63 {
64   if (T.Form() == gp_Identity || T.Form() == gp_Translation)    { }
65   else if (T.Form() == gp_PntMirror) { coord.Reverse(); }
66   else if (T.Form() == gp_Scale) {
67     if (T.ScaleFactor() < 0.0) { coord.Reverse(); }
68   }
69   else {
70     coord.Multiply (T.HVectorialPart());
71     Standard_Real D = coord.Modulus();
72     coord.Divide(D);
73     if (T.ScaleFactor() < 0.0) { coord.Reverse(); }
74   } 
75 }
76
77 void gp_Dir2d::Mirror (const gp_Dir2d& V)
78 {
79   const gp_XY& XY = V.coord;
80   Standard_Real A = XY.X();
81   Standard_Real B = XY.Y();
82   Standard_Real X = coord.X();
83   Standard_Real Y = coord.Y();
84   Standard_Real M1 = 2.0 * A * B;
85   Standard_Real XX = ((2.0 * A * A) - 1.0) * X + M1 * Y;
86   Standard_Real YY = M1 * X + ((2.0 * B * B) - 1.0) * Y;
87   coord.SetCoord(XX,YY);
88 }
89
90 gp_Dir2d gp_Dir2d::Mirrored (const gp_Dir2d& V) const
91 {
92   gp_Dir2d Vres = *this;
93   Vres.Mirror (V);
94   return Vres;
95 }
96
97 gp_Dir2d gp_Dir2d::Mirrored (const gp_Ax2d& A) const
98 {
99   gp_Dir2d V = *this;
100   V.Mirror (A);
101   return V;
102 }
103