0028636: Optimisation of gp_* classes in order to avoid unnecesary calling gp_Dir...
[occt.git] / src / gp / gp_Ax2.lxx
1 // Copyright (c) 1996-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 #include <Precision.hxx>
16
17 inline gp_Ax2::gp_Ax2()
18   :
19   vydir(0.,1.,0.)
20   // vxdir(1.,0.,0.) use default ctor of gp_Dir, as it creates the same dir(1,0,0)
21 { }
22
23 inline gp_Ax2::gp_Ax2(const gp_Pnt& P,
24                       const gp_Dir& N,
25                       const gp_Dir& Vx) : axis(P, N), vydir(N), vxdir(N)
26 {
27   vxdir.CrossCross(Vx, N);
28   vydir.Cross(vxdir);
29 }
30
31 inline void gp_Ax2::SetAxis (const gp_Ax1&  A1)
32 {
33   Standard_Real a =  A1.Direction() * vxdir;
34   if(Abs(Abs(a) - 1.) <= Precision::Angular()) {
35     if(a > 0.) {
36       vxdir = vydir;
37       vydir = axis.Direction();
38       axis = A1;
39     }
40     else {
41       vxdir = axis.Direction();
42       axis = A1;
43     }
44   }
45   else {
46     axis = A1;
47     vxdir = axis.Direction().CrossCrossed (vxdir, axis.Direction());
48     vydir = axis.Direction().Crossed      (vxdir);
49   }
50 }
51
52 inline void gp_Ax2::SetDirection (const gp_Dir&  V)
53
54   Standard_Real a =  V * vxdir;
55   if(Abs(Abs(a) - 1.) <= Precision::Angular()) {
56     if(a > 0.) {
57       vxdir = vydir;
58       vydir = axis.Direction();
59       axis.SetDirection (V);
60     }
61     else {
62       vxdir = axis.Direction();
63       axis.SetDirection (V);
64     }
65   }
66   else {
67     axis.SetDirection (V);
68     vxdir = V.CrossCrossed (vxdir, V);
69     vydir = V.Crossed (vxdir);
70   }
71 }
72
73 inline void gp_Ax2::SetLocation (const gp_Pnt& P)
74 { axis.SetLocation(P); }
75
76 inline void gp_Ax2::SetXDirection (const gp_Dir&  Vx)
77 {
78   vxdir = axis.Direction().CrossCrossed (Vx, axis.Direction());
79   vydir = axis.Direction().Crossed      (vxdir);
80 }
81
82 inline void gp_Ax2::SetYDirection (const gp_Dir& Vy)
83 {
84   vxdir = Vy.Crossed (axis.Direction());
85   vydir = (axis.Direction()).Crossed (vxdir);
86 }
87
88 inline Standard_Real gp_Ax2::Angle (const gp_Ax2& Other) const
89 { return axis.Angle (Other.axis); }
90
91 inline const gp_Ax1& gp_Ax2::Axis () const
92 { return axis; }
93
94 inline const gp_Dir& gp_Ax2::Direction () const
95 { return axis.Direction(); }
96
97 inline const gp_Pnt& gp_Ax2::Location () const
98 { return axis.Location(); }
99
100 inline const gp_Dir& gp_Ax2::XDirection () const
101 { return vxdir; }
102
103 inline const gp_Dir& gp_Ax2::YDirection () const
104 { return vydir; }
105
106 inline Standard_Boolean gp_Ax2::IsCoplanar 
107 (const gp_Ax2& Other,
108  const Standard_Real LinearTolerance,
109  const Standard_Real AngularTolerance) const
110 {
111   const gp_Dir& DD =       axis.Direction();
112   const gp_Pnt& PP =       axis.Location ();
113   const gp_Pnt& OP = Other.axis.Location ();
114   Standard_Real D1 = (DD.X() * (OP.X() - PP.X()) + 
115                       DD.Y() * (OP.Y() - PP.Y()) + 
116                       DD.Z() * (OP.Z() - PP.Z()));
117   if (D1 < 0 ) D1 = - D1;
118   return (D1 <= LinearTolerance &&
119           axis.IsParallel (Other.axis, AngularTolerance));
120 }
121
122 inline Standard_Boolean gp_Ax2::IsCoplanar
123 (const gp_Ax1& A,
124  const Standard_Real LinearTolerance,
125  const Standard_Real AngularTolerance) const
126 {
127   const gp_Dir& DD = axis.Direction();
128   const gp_Pnt& PP = axis.Location ();
129   const gp_Pnt& AP = A   .Location ();
130   Standard_Real D1 = (DD.X() * (AP.X() - PP.X()) + 
131                       DD.Y() * (AP.Y() - PP.Y()) + 
132                       DD.Z() * (AP.Z() - PP.Z()));
133   if (D1 < 0) D1 = - D1;
134   return (D1 <= LinearTolerance &&
135           axis.IsNormal (A, AngularTolerance));
136 }
137
138 inline void gp_Ax2::Rotate(const gp_Ax1& A1, const Standard_Real Ang)
139 {
140   gp_Pnt Temp = axis.Location();
141   Temp.Rotate  (A1, Ang);
142   axis.SetLocation (Temp);
143   vxdir.Rotate (A1, Ang);
144   vydir.Rotate (A1, Ang);
145   axis.SetDirection (vxdir.Crossed (vydir));
146 }
147
148 inline gp_Ax2 gp_Ax2::Rotated(const gp_Ax1& A1,
149                               const Standard_Real Ang) const
150 {
151   gp_Ax2 Temp = *this;
152   Temp.Rotate (A1, Ang);
153   return Temp;
154
155
156 inline void gp_Ax2::Scale (const gp_Pnt& P, const Standard_Real S)
157 {
158   gp_Pnt Temp = axis.Location();
159   Temp.Scale (P, S);
160   axis.SetLocation (Temp);
161   if (S < 0.0) {
162     vxdir.Reverse ();
163     vydir.Reverse ();
164   }
165 }
166
167 inline gp_Ax2 gp_Ax2::Scaled(const gp_Pnt& P,
168                              const Standard_Real S) const 
169 {
170   gp_Ax2 Temp = *this;
171   Temp.Scale (P, S);
172   return Temp;
173 }
174
175 inline void gp_Ax2::Transform (const gp_Trsf& T)
176 {
177   gp_Pnt Temp = axis.Location();
178   Temp.Transform (T);
179   axis.SetLocation (Temp);
180   vxdir.Transform (T);
181   vydir.Transform (T);
182   axis.SetDirection (vxdir.Crossed (vydir));
183 }
184
185 inline gp_Ax2 gp_Ax2::Transformed(const gp_Trsf& T) const
186 {
187   gp_Ax2 Temp = *this;
188   Temp.Transform (T);
189   return Temp;
190 }
191
192 inline void gp_Ax2::Translate (const gp_Vec& V)
193 { axis.Translate (V); }
194
195 inline gp_Ax2 gp_Ax2::Translated(const gp_Vec& V) const
196 {
197   gp_Ax2 Temp = *this;
198   Temp.Translate (V);
199   return Temp;
200 }
201
202 inline void gp_Ax2::Translate (const gp_Pnt& P1, const gp_Pnt& P2)
203 { axis.Translate (P1, P2); }
204
205 inline gp_Ax2 gp_Ax2::Translated (const gp_Pnt& P1,
206                                   const gp_Pnt& P2)  const
207 {
208   gp_Ax2 Temp = *this;
209   Temp.Translate (P1, P2);
210   return Temp;
211 }
212