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