0032137: Coding Rules - merge redundant .lxx files into header files within Package gp
[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_Dir2d.hxx>
18
19 #include <gp_Ax2d.hxx>
20 #include <gp_Trsf2d.hxx>
21 #include <gp_Vec2d.hxx>
22 #include <gp_XY.hxx>
23 #include <Standard_ConstructionError.hxx>
24 #include <Standard_DomainError.hxx>
25 #include <Standard_Dump.hxx>
26 #include <Standard_OutOfRange.hxx>
27
28 Standard_Real gp_Dir2d::Angle (const gp_Dir2d& Other) const
29 {
30   //    Commentaires :
31   //    Au dessus de 45 degres l'arccos donne la meilleur precision pour le
32   //    calcul de l'angle. Sinon il vaut mieux utiliser l'arcsin.
33   //    Les erreurs commises sont loin d'etre negligeables lorsque l'on est
34   //    proche de zero ou de 90 degres.
35   //    En 2D les valeurs angulaires sont comprises entre -PI et PI
36   Standard_Real Cosinus = coord.Dot   (Other.coord);
37   Standard_Real Sinus = coord.Crossed (Other.coord);
38   if (Cosinus > -0.70710678118655 && Cosinus < 0.70710678118655) { 
39     if (Sinus > 0.0) return   acos (Cosinus);
40     else             return - acos (Cosinus);
41   }
42   else {
43     if (Cosinus > 0.0)  return      asin (Sinus);
44     else { 
45       if (Sinus > 0.0) return  M_PI - asin (Sinus);
46       else             return -M_PI - asin (Sinus);
47     }
48   }
49 }
50
51 void gp_Dir2d::Mirror (const gp_Ax2d& A2)
52 {
53   const gp_XY& XY = A2.Direction().XY();
54   Standard_Real A = XY.X();
55   Standard_Real B = XY.Y();
56   Standard_Real X = coord.X();
57   Standard_Real Y = coord.Y();
58   Standard_Real M1 = 2.0 * A * B;
59   Standard_Real XX = ((2.0 * A * A) - 1.0) * X + M1 * Y;
60   Standard_Real YY = M1 * X + ((2.0 * B * B) - 1.0) * Y;
61   coord.SetCoord(XX,YY);
62 }
63
64 void gp_Dir2d::Transform (const gp_Trsf2d& T)
65 {
66   if (T.Form() == gp_Identity || T.Form() == gp_Translation)    { }
67   else if (T.Form() == gp_PntMirror) { coord.Reverse(); }
68   else if (T.Form() == gp_Scale) {
69     if (T.ScaleFactor() < 0.0) { coord.Reverse(); }
70   }
71   else {
72     coord.Multiply (T.HVectorialPart());
73     Standard_Real D = coord.Modulus();
74     coord.Divide(D);
75     if (T.ScaleFactor() < 0.0) { coord.Reverse(); }
76   } 
77 }
78
79 void gp_Dir2d::Mirror (const gp_Dir2d& V)
80 {
81   const gp_XY& XY = V.coord;
82   Standard_Real A = XY.X();
83   Standard_Real B = XY.Y();
84   Standard_Real X = coord.X();
85   Standard_Real Y = coord.Y();
86   Standard_Real M1 = 2.0 * A * B;
87   Standard_Real XX = ((2.0 * A * A) - 1.0) * X + M1 * Y;
88   Standard_Real YY = M1 * X + ((2.0 * B * B) - 1.0) * Y;
89   coord.SetCoord(XX,YY);
90 }
91
92 gp_Dir2d gp_Dir2d::Mirrored (const gp_Dir2d& V) const
93 {
94   gp_Dir2d Vres = *this;
95   Vres.Mirror (V);
96   return Vres;
97 }
98
99 gp_Dir2d gp_Dir2d::Mirrored (const gp_Ax2d& A) const
100 {
101   gp_Dir2d V = *this;
102   V.Mirror (A);
103   return V;
104 }
105
106 void gp_Dir2d::DumpJson (Standard_OStream& theOStream, Standard_Integer) const
107 {
108   OCCT_DUMP_VECTOR_CLASS (theOStream, "gp_Dir2d", 2, coord.X(), coord.Y())
109 }