40283e9469df64974ca408790a2c21663a420513
[occt.git] / src / gp / gp_Vec.lxx
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 // Modif JCV 07/12/90 introduction classe XYZ dans le package gp
16 // LPA et JCV 07/92 mise a jour
17
18 #include <gp.hxx>
19 #include <gp_Dir.hxx>
20 #include <gp_Pnt.hxx>
21 #include <gp_Trsf.hxx>
22 #include <gp_VectorWithNullMagnitude.hxx>
23 #include <Standard_ConstructionError.hxx>
24
25 inline gp_Vec::gp_Vec() { }
26
27 inline gp_Vec::gp_Vec (const gp_Dir& V) { coord = V.XYZ(); }
28
29 inline gp_Vec::gp_Vec (const gp_XYZ& Coord) : coord(Coord) { }
30
31 inline gp_Vec::gp_Vec (const Standard_Real Xv,
32                        const Standard_Real Yv,
33                        const Standard_Real Zv)
34                : coord (Xv, Yv, Zv)   { }
35
36 inline gp_Vec::gp_Vec (const gp_Pnt& P1,
37                        const gp_Pnt& P2)
38 { coord = P2.XYZ().Subtracted(P1.XYZ()); }
39
40 inline void gp_Vec::SetCoord (const Standard_Integer Index,
41                               const Standard_Real Xi)
42 { coord.SetCoord (Index, Xi); }
43
44 inline void gp_Vec::SetCoord (const Standard_Real Xv,
45                               const Standard_Real Yv,
46                               const Standard_Real Zv)
47 {
48   coord.SetX(Xv);
49   coord.SetY(Yv);
50   coord.SetZ(Zv);
51 }
52
53 inline void gp_Vec::SetX (const Standard_Real X)
54 { coord.SetX (X); }
55
56 inline void gp_Vec::SetY (const Standard_Real Y)
57 { coord.SetY (Y); }
58
59 inline void gp_Vec::SetZ (const Standard_Real Z)
60 { coord.SetZ (Z); }
61
62 inline void gp_Vec::SetXYZ (const gp_XYZ& Coord)
63 { coord = Coord; }
64
65 inline Standard_Real gp_Vec::Coord (const Standard_Integer Index) const
66 { return coord.Coord (Index); }
67
68 inline void gp_Vec::Coord(Standard_Real& Xv, 
69                           Standard_Real& Yv,
70                           Standard_Real& Zv) const
71 {
72   Xv = coord.X();
73   Yv = coord.Y();
74   Zv = coord.Z();
75 }
76
77 inline Standard_Real gp_Vec::X() const
78 { return coord.X(); }
79      
80 inline Standard_Real gp_Vec::Y() const
81 { return coord.Y(); }
82
83 inline Standard_Real gp_Vec::Z() const
84 { return coord.Z(); }
85      
86 inline const gp_XYZ& gp_Vec::XYZ () const
87 { return coord; }
88
89 inline Standard_Boolean gp_Vec::IsNormal
90 (const gp_Vec& Other,
91  const Standard_Real AngularTolerance) const
92 {
93   Standard_Real Ang = M_PI / 2.0 - Angle(Other);
94   if (Ang < 0) Ang = - Ang;
95   return  Ang <= AngularTolerance;
96 }    
97
98 inline Standard_Boolean gp_Vec::IsOpposite
99 (const gp_Vec& Other,
100  const Standard_Real AngularTolerance) const
101 {
102   Standard_Real Ang = M_PI - Angle(Other);
103   return Ang <= AngularTolerance;
104 }    
105
106 inline Standard_Boolean gp_Vec::IsParallel
107 (const gp_Vec& Other,
108  const Standard_Real AngularTolerance) const
109 {
110   Standard_Real Ang = Angle (Other);
111   return   Ang <= AngularTolerance || M_PI - Ang <= AngularTolerance;
112 }    
113
114 inline Standard_Real gp_Vec::Angle (const gp_Vec& Other) const
115 {
116   //    Commentaires :
117   //    Au dessus de 45 degres l'arccos donne la meilleur precision pour le
118   //    calcul de l'angle. Sinon il vaut mieux utiliser l'arcsin.
119   //    Les erreurs commises sont loin d'etre negligeables lorsque l'on est
120   //    proche de zero ou de 90 degres.
121   //    En 3d les valeurs angulaires sont toujours positives et comprises entre
122   //    0 et Pi.
123   
124   gp_VectorWithNullMagnitude_Raise_if
125     (coord.Modulus()       <= gp::Resolution() ||
126      Other.coord.Modulus() <= gp::Resolution(), " ");
127   return (gp_Dir(coord)).Angle(Other);
128 }
129
130 inline Standard_Real gp_Vec::AngleWithRef (const gp_Vec& Other,
131                                            const gp_Vec& Vref) const
132 {
133   gp_VectorWithNullMagnitude_Raise_if
134     (coord.Modulus()       <= gp::Resolution() ||
135      Vref.coord.Modulus () <= gp::Resolution() ||
136      Other.coord.Modulus() <= gp::Resolution(), " ");
137   return (gp_Dir(coord)).AngleWithRef(Other,Vref);
138
139
140 inline Standard_Real gp_Vec::Magnitude() const
141 { return coord.Modulus(); }
142
143 inline Standard_Real gp_Vec::SquareMagnitude() const
144 { return coord.SquareModulus(); }
145
146 inline void gp_Vec::Add (const gp_Vec& Other)
147 { coord.Add (Other.coord); }
148
149 inline gp_Vec gp_Vec::Added (const gp_Vec& Other) const
150 {
151   gp_Vec V = *this;
152   V.coord.Add (Other.coord);
153   return V;
154 }
155
156 inline void gp_Vec::Subtract (const gp_Vec& Right)
157 { coord.Subtract (Right.coord); }
158
159 inline gp_Vec gp_Vec::Subtracted (const gp_Vec& Right) const
160 {
161   gp_Vec V = *this;
162    V.coord.Subtract(Right.coord);
163    return V;
164 }
165
166 inline void gp_Vec::Multiply (const Standard_Real Scalar)
167 { coord.Multiply(Scalar); }
168
169 inline gp_Vec gp_Vec::Multiplied (const Standard_Real Scalar) const
170 {
171   gp_Vec V = *this;
172   V.coord.Multiply (Scalar);
173   return V;
174 }
175
176 inline void gp_Vec::Divide (const Standard_Real Scalar)
177 { coord.Divide (Scalar); }
178
179 inline gp_Vec gp_Vec::Divided (const Standard_Real Scalar) const
180 {
181   gp_Vec V = *this;
182   V.coord.Divide (Scalar);
183   return V;
184 }
185
186 inline void gp_Vec::Cross (const gp_Vec& Right)
187 { coord.Cross (Right.coord); }
188
189 inline gp_Vec gp_Vec::Crossed (const gp_Vec& Right) const
190 {
191   gp_Vec V = *this;
192   V.coord.Cross (Right.coord);
193   return V;
194 }
195
196 inline Standard_Real gp_Vec::CrossMagnitude
197 (const gp_Vec& Right) const
198 { return coord.CrossMagnitude (Right.coord); }
199
200 inline Standard_Real gp_Vec::CrossSquareMagnitude
201 (const gp_Vec& Right) const
202 { return coord.CrossSquareMagnitude (Right.coord); }
203
204 inline void gp_Vec::CrossCross (const gp_Vec& V1,
205                                 const gp_Vec& V2)
206 { coord.CrossCross(V1.coord, V2.coord); }
207
208 inline gp_Vec gp_Vec::CrossCrossed (const gp_Vec& V1,
209                                     const gp_Vec& V2) const
210 {
211   gp_Vec V = *this;
212   V.coord.CrossCross(V1.coord, V2.coord);
213   return V;
214 }
215
216 inline Standard_Real gp_Vec::Dot (const gp_Vec& Other) const
217 { return coord.Dot (Other.coord); }
218
219 inline Standard_Real gp_Vec::DotCross (const gp_Vec& V1,
220                                        const gp_Vec& V2)  const
221 { return coord.DotCross (V1.coord, V2.coord); } 
222
223 inline void gp_Vec::Normalize()
224
225   Standard_Real D = coord.Modulus();
226   Standard_ConstructionError_Raise_if (D <= gp::Resolution(),
227                                        "gp_Vec::Normalize() - vector has zero norm");
228   coord.Divide (D);
229 }
230
231 inline gp_Vec gp_Vec::Normalized() const
232
233   Standard_Real D = coord.Modulus();
234   Standard_ConstructionError_Raise_if (D <= gp::Resolution(),
235                                        "gp_Vec::Normalized() - vector has zero norm");
236   gp_Vec V = *this;
237   V.coord.Divide (D);
238   return V; 
239 }
240
241 inline void gp_Vec::Reverse()
242 { coord.Reverse(); }
243
244 inline gp_Vec gp_Vec::Reversed () const
245 {
246   gp_Vec V = *this;
247   V.coord.Reverse();
248   return V;
249 }
250
251 inline void gp_Vec::SetLinearForm
252 (const Standard_Real L,
253  const gp_Vec& Left,
254  const Standard_Real R,
255  const gp_Vec& Right)
256 { coord.SetLinearForm (L, Left.coord, R, Right.coord); }
257
258 inline void gp_Vec::SetLinearForm
259 (const Standard_Real L,
260  const gp_Vec& Left,
261  const gp_Vec& Right)
262 { coord.SetLinearForm (L, Left.coord, Right.coord); }
263
264 inline void gp_Vec::SetLinearForm
265 (const gp_Vec& Left,
266  const gp_Vec& Right)
267 { coord.SetLinearForm (Left.coord,  Right.coord); }
268
269 inline void gp_Vec::SetLinearForm
270 (const Standard_Real A1, const gp_Vec& V1, 
271  const Standard_Real A2, const gp_Vec& V2,
272  const Standard_Real A3, const gp_Vec& V3)
273 { coord.SetLinearForm (A1, V1.coord, A2, V2.coord, A3, V3.coord); }
274
275 inline void gp_Vec::SetLinearForm
276 (const Standard_Real A1, const gp_Vec& V1, 
277  const Standard_Real A2, const gp_Vec& V2, 
278  const gp_Vec& V3)
279 { coord.SetLinearForm (A1, V1.coord, A2, V2.coord, V3.coord); }
280
281 inline void gp_Vec::SetLinearForm
282 (const Standard_Real A1, const gp_Vec& V1,
283  const Standard_Real A2, const gp_Vec& V2,
284  const Standard_Real A3, const gp_Vec& V3,
285  const gp_Vec& V4)
286 { coord.SetLinearForm(A1,V1.coord,A2,V2.coord,A3,V3.coord,V4.coord); }
287
288 inline void gp_Vec::Rotate (const gp_Ax1& A1,
289                             const Standard_Real Ang)
290 {
291   gp_Trsf T;
292   T.SetRotation (A1, Ang);
293   coord.Multiply (T.VectorialPart());
294 }
295
296 inline gp_Vec gp_Vec::Rotated (const gp_Ax1& A1,
297                                const Standard_Real Ang) const
298 {
299   gp_Vec Vres = *this;
300   Vres.Rotate (A1, Ang);
301   return Vres;                     
302 }
303
304 inline void gp_Vec::Scale (const Standard_Real S)
305 { coord.Multiply (S); }
306
307 inline gp_Vec gp_Vec::Scaled (const Standard_Real S) const
308 {
309   gp_Vec V = *this;
310   V.coord.Multiply(S);
311   return V;
312 }
313
314 inline gp_Vec gp_Vec::Transformed (const gp_Trsf& T) const
315 {
316   gp_Vec V = *this;
317   V.Transform(T);
318   return V;
319
320
321 inline gp_Vec operator* (const Standard_Real Scalar, const gp_Vec& V) {
322  return V.Multiplied(Scalar);
323 }
324