0032137: Coding Rules - merge redundant .lxx files into header files within Package gp
[occt.git] / src / gp / gp_Vec.hxx
1 // Copyright (c) 1991-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 #ifndef _gp_Vec_HeaderFile
16 #define _gp_Vec_HeaderFile
17
18 #include <gp_VectorWithNullMagnitude.hxx>
19 #include <gp_XYZ.hxx>
20 #include <Standard_ConstructionError.hxx>
21 #include <Standard_DomainError.hxx>
22 #include <Standard_OutOfRange.hxx>
23
24 class gp_Dir;
25 class gp_Pnt;
26 class gp_Ax1;
27 class gp_Ax2;
28 class gp_Trsf;
29
30 //! Defines a non-persistent vector in 3D space.
31 class gp_Vec 
32 {
33 public:
34
35   DEFINE_STANDARD_ALLOC
36
37   //! Creates a zero vector.
38   gp_Vec() {}
39
40   //! Creates a unitary vector from a direction theV.
41   gp_Vec (const gp_Dir& theV);
42
43   //! Creates a vector with a triplet of coordinates.
44   gp_Vec (const gp_XYZ& theCoord)
45   : coord (theCoord)
46   {}
47
48   //! Creates a point with its three cartesian coordinates.
49   gp_Vec (const Standard_Real theXv, const Standard_Real theYv, const Standard_Real theZv)
50   : coord (theXv, theYv, theZv)
51   {}
52
53   //! Creates a vector from two points. The length of the vector
54   //! is the distance between theP1 and theP2
55   gp_Vec (const gp_Pnt& theP1, const gp_Pnt& theP2);
56
57   //! Changes the coordinate of range theIndex
58   //! theIndex = 1 => X is modified
59   //! theIndex = 2 => Y is modified
60   //! theIndex = 3 => Z is modified
61   //! Raised if theIndex != {1, 2, 3}.
62   void SetCoord (const Standard_Integer theIndex, const Standard_Real theXi) { coord.SetCoord (theIndex, theXi); }
63
64   //! For this vector, assigns
65   //! -   the values theXv, theYv and theZv to its three coordinates.
66   void SetCoord (const Standard_Real theXv, const Standard_Real theYv, const Standard_Real theZv)
67   {
68     coord.SetX (theXv);
69     coord.SetY (theYv);
70     coord.SetZ (theZv);
71   }
72
73   //! Assigns the given value to the X coordinate of this vector.
74   void SetX (const Standard_Real theX) { coord.SetX(theX); }
75
76   //! Assigns the given value to the X coordinate of this vector.
77   void SetY (const Standard_Real theY) { coord.SetY (theY); }
78
79   //! Assigns the given value to the X coordinate of this vector.
80   void SetZ (const Standard_Real theZ) { coord.SetZ (theZ); }
81
82   //! Assigns the three coordinates of theCoord to this vector.
83   void SetXYZ (const gp_XYZ& theCoord) { coord = theCoord; }
84
85   //! Returns the coordinate of range theIndex :
86   //! theIndex = 1 => X is returned
87   //! theIndex = 2 => Y is returned
88   //! theIndex = 3 => Z is returned
89   //! Raised if theIndex != {1, 2, 3}.
90   Standard_Real Coord (const Standard_Integer theIndex) const { return coord.Coord (theIndex); }
91
92   //! For this vector returns its three coordinates theXv, theYv, and theZv inline
93   void Coord (Standard_Real& theXv, Standard_Real& theYv, Standard_Real& theZv) const
94   {
95     theXv = coord.X();
96     theYv = coord.Y();
97     theZv = coord.Z();
98   }
99
100   //! For this vector, returns its X coordinate.
101   Standard_Real X() const { return coord.X(); }
102
103   //! For this vector, returns its Y coordinate.
104   Standard_Real Y() const { return coord.Y(); }
105
106   //! For this vector, returns its Z  coordinate.
107   Standard_Real Z() const { return coord.Z(); }
108
109   //! For this vector, returns
110   //! -   its three coordinates as a number triple
111   const gp_XYZ& XYZ() const { return coord; }
112
113   //! Returns True if the two vectors have the same magnitude value
114   //! and the same direction. The precision values are theLinearTolerance
115   //! for the magnitude and theAngularTolerance for the direction.
116   Standard_EXPORT Standard_Boolean IsEqual (const gp_Vec& theOther, const Standard_Real theLinearTolerance, const Standard_Real theAngularTolerance) const;
117
118   //! Returns True if abs(<me>.Angle(theOther) - PI/2.) <= theAngularTolerance
119   //! Raises VectorWithNullMagnitude if <me>.Magnitude() <= Resolution or
120   //! theOther.Magnitude() <= Resolution from gp
121   Standard_Boolean IsNormal (const gp_Vec& theOther, const Standard_Real theAngularTolerance) const;
122
123   //! Returns True if PI - <me>.Angle(theOther) <= theAngularTolerance
124   //! Raises VectorWithNullMagnitude if <me>.Magnitude() <= Resolution or
125   //! Other.Magnitude() <= Resolution from gp
126   Standard_Boolean IsOpposite (const gp_Vec& theOther, const Standard_Real theAngularTolerance) const
127   {
128     Standard_Real anAng = M_PI - Angle (theOther);
129     return anAng <= theAngularTolerance;
130   }
131
132   //! Returns True if Angle(<me>, theOther) <= theAngularTolerance or
133   //! PI - Angle(<me>, theOther) <= theAngularTolerance
134   //! This definition means that two parallel vectors cannot define
135   //! a plane but two vectors with opposite directions are considered
136   //! as parallel. Raises VectorWithNullMagnitude if <me>.Magnitude() <= Resolution or
137   //! Other.Magnitude() <= Resolution from gp
138   Standard_Boolean IsParallel (const gp_Vec& theOther, const Standard_Real theAngularTolerance) const
139   {
140     Standard_Real anAng = Angle (theOther);
141     return anAng <= theAngularTolerance || M_PI - anAng <= theAngularTolerance;
142   }
143
144   //! Computes the angular value between <me> and <theOther>
145   //! Returns the angle value between 0 and PI in radian.
146   //! Raises VectorWithNullMagnitude if <me>.Magnitude() <= Resolution from gp or
147   //! theOther.Magnitude() <= Resolution because the angular value is
148   //! indefinite if one of the vectors has a null magnitude.
149   Standard_Real Angle (const gp_Vec& theOther) const;
150
151   //! Computes the angle, in radians, between this vector and
152   //! vector theOther. The result is a value between -Pi and Pi.
153   //! For this, theVRef defines the positive sense of rotation: the
154   //! angular value is positive, if the cross product this ^ theOther
155   //! has the same orientation as theVRef relative to the plane
156   //! defined by the vectors this and theOther. Otherwise, the
157   //! angular value is negative.
158   //! Exceptions
159   //! gp_VectorWithNullMagnitude if the magnitude of this
160   //! vector, the vector theOther, or the vector theVRef is less than or
161   //! equal to gp::Resolution().
162   //! Standard_DomainError if this vector, the vector theOther,
163   //! and the vector theVRef are coplanar, unless this vector and
164   //! the vector theOther are parallel.
165   Standard_Real AngleWithRef (const gp_Vec& theOther, const gp_Vec& theVRef) const;
166
167   //! Computes the magnitude of this vector.
168   Standard_Real Magnitude() const { return coord.Modulus(); }
169
170   //! Computes the square magnitude of this vector.
171   Standard_Real SquareMagnitude() const { return coord.SquareModulus(); }
172
173   //! Adds two vectors
174   void Add (const gp_Vec& theOther) { coord.Add (theOther.coord); }
175
176   void operator += (const gp_Vec& theOther) { Add (theOther); }
177
178   //! Adds two vectors
179   Standard_NODISCARD gp_Vec Added (const gp_Vec& theOther) const
180   {
181     gp_Vec aV = *this;
182     aV.coord.Add (theOther.coord);
183     return aV;
184   }
185
186   Standard_NODISCARD gp_Vec operator + (const gp_Vec& theOther) const { return Added (theOther); }
187
188   //! Subtracts two vectors
189   void Subtract (const gp_Vec& theRight) { coord.Subtract (theRight.coord); }
190
191   void operator -= (const gp_Vec& theRight) { Subtract (theRight); }
192
193   //! Subtracts two vectors
194   Standard_NODISCARD gp_Vec Subtracted (const gp_Vec& theRight) const
195   {
196     gp_Vec aV = *this;
197     aV.coord.Subtract (theRight.coord);
198     return aV;
199   }
200
201   Standard_NODISCARD gp_Vec operator - (const gp_Vec& theRight) const { return Subtracted (theRight); }
202
203   //! Multiplies a vector by a scalar
204   void Multiply (const Standard_Real theScalar) { coord.Multiply (theScalar); }
205
206   void operator *= (const Standard_Real theScalar) { Multiply (theScalar); }
207
208   //! Multiplies a vector by a scalar
209   Standard_NODISCARD gp_Vec Multiplied (const Standard_Real theScalar) const
210   {
211     gp_Vec aV = *this;
212     aV.coord.Multiply (theScalar);
213     return aV;
214   }
215
216   Standard_NODISCARD gp_Vec operator * (const Standard_Real theScalar) const { return Multiplied (theScalar); }
217
218   //! Divides a vector by a scalar
219   void Divide (const Standard_Real theScalar) { coord.Divide (theScalar); }
220
221   void operator /= (const Standard_Real theScalar) { Divide (theScalar); }
222
223   //! Divides a vector by a scalar
224   Standard_NODISCARD gp_Vec Divided (const Standard_Real theScalar) const
225   {
226     gp_Vec aV = *this;
227     aV.coord.Divide (theScalar);
228     return aV;
229   }
230
231   Standard_NODISCARD gp_Vec operator / (const Standard_Real theScalar) const { return Divided (theScalar); }
232
233   //! computes the cross product between two vectors
234   void Cross (const gp_Vec& theRight) { coord.Cross (theRight.coord); }
235
236   void operator ^= (const gp_Vec& theRight) { Cross (theRight); }
237
238   //! computes the cross product between two vectors
239   Standard_NODISCARD gp_Vec Crossed (const gp_Vec& theRight) const
240   {
241     gp_Vec aV = *this;
242     aV.coord.Cross (theRight.coord);
243     return aV;
244   }
245
246   Standard_NODISCARD gp_Vec operator ^ (const gp_Vec& theRight) const { return Crossed (theRight); }
247
248   //! Computes the magnitude of the cross
249   //! product between <me> and theRight.
250   //! Returns || <me> ^ theRight ||
251   Standard_Real CrossMagnitude (const gp_Vec& theRight) const { return coord.CrossMagnitude (theRight.coord); }
252
253   //! Computes the square magnitude of
254   //! the cross product between <me> and theRight.
255   //! Returns || <me> ^ theRight ||**2
256   Standard_Real CrossSquareMagnitude (const gp_Vec& theRight) const
257   {
258     return coord.CrossSquareMagnitude (theRight.coord);
259   }
260
261   //! Computes the triple vector product.
262   //! <me> ^= (theV1 ^ theV2)
263   void CrossCross (const gp_Vec& theV1, const gp_Vec& theV2)
264   {
265     coord.CrossCross (theV1.coord, theV2.coord);
266   }
267
268   //! Computes the triple vector product.
269   //! <me> ^ (theV1 ^ theV2)
270   Standard_NODISCARD gp_Vec CrossCrossed (const gp_Vec& theV1, const gp_Vec& theV2) const
271   {
272     gp_Vec aV = *this;
273     aV.coord.CrossCross (theV1.coord, theV2.coord);
274     return aV;
275   }
276
277   //! computes the scalar product
278   Standard_Real Dot (const gp_Vec& theOther) const { return coord.Dot (theOther.coord); }
279
280   Standard_Real operator * (const gp_Vec& theOther) const { return Dot (theOther); }
281
282   //! Computes the triple scalar product <me> * (theV1 ^ theV2).
283   Standard_Real DotCross (const gp_Vec& theV1, const gp_Vec& theV2) const
284   {
285     return coord.DotCross (theV1.coord, theV2.coord);
286   }
287
288   //! normalizes a vector
289   //! Raises an exception if the magnitude of the vector is
290   //! lower or equal to Resolution from gp.
291   void Normalize()
292   {
293     Standard_Real aD = coord.Modulus();
294     Standard_ConstructionError_Raise_if (aD <= gp::Resolution(), "gp_Vec::Normalize() - vector has zero norm");
295     coord.Divide (aD);
296   }
297
298   //! normalizes a vector
299   //! Raises an exception if the magnitude of the vector is
300   //! lower or equal to Resolution from gp.
301   Standard_NODISCARD gp_Vec Normalized() const;
302
303   //! Reverses the direction of a vector
304   void Reverse() { coord.Reverse(); }
305
306   //! Reverses the direction of a vector
307   Standard_NODISCARD gp_Vec Reversed() const
308   {
309     gp_Vec aV = *this;
310     aV.coord.Reverse();
311     return aV;
312   }
313
314   Standard_NODISCARD gp_Vec operator -() const { return Reversed(); }
315
316   //! <me> is set to the following linear form :
317   //! theA1 * theV1 + theA2 * theV2 + theA3 * theV3 + theV4
318   void SetLinearForm (const Standard_Real theA1, const gp_Vec& theV1,
319                       const Standard_Real theA2, const gp_Vec& theV2,
320                       const Standard_Real theA3, const gp_Vec& theV3, const gp_Vec& theV4)
321   {
322     coord.SetLinearForm (theA1, theV1.coord, theA2, theV2.coord, theA3, theV3.coord, theV4.coord);
323   }
324
325   //! <me> is set to the following linear form :
326   //! theA1 * theV1 + theA2 * theV2 + theA3 * theV3
327   void SetLinearForm (const Standard_Real theA1, const gp_Vec& theV1,
328                       const Standard_Real theA2, const gp_Vec& theV2,
329                       const Standard_Real theA3, const gp_Vec& theV3)
330   {
331     coord.SetLinearForm (theA1, theV1.coord, theA2, theV2.coord, theA3, theV3.coord);
332   }
333
334   //! <me> is set to the following linear form :
335   //! theA1 * theV1 + theA2 * theV2 + theV3
336   void SetLinearForm (const Standard_Real theA1, const gp_Vec& theV1,
337                       const Standard_Real theA2, const gp_Vec& theV2, const gp_Vec& theV3)
338   {
339     coord.SetLinearForm (theA1, theV1.coord, theA2, theV2.coord, theV3.coord);
340   }
341
342   //! <me> is set to the following linear form :
343   //! theA1 * theV1 + theA2 * theV2
344   void SetLinearForm (const Standard_Real theA1, const gp_Vec& theV1,
345                       const Standard_Real theA2, const gp_Vec& theV2)
346   {
347     coord.SetLinearForm (theA1, theV1.coord, theA2, theV2.coord);
348   }
349
350   //! <me> is set to the following linear form : theA1 * theV1 + theV2
351   void SetLinearForm (const Standard_Real theA1, const gp_Vec& theV1, const gp_Vec& theV2)
352   {
353     coord.SetLinearForm (theA1, theV1.coord, theV2.coord);
354   }
355
356   //! <me> is set to the following linear form : theV1 + theV2
357   void SetLinearForm (const gp_Vec& theV1, const gp_Vec& theV2)
358   {
359     coord.SetLinearForm (theV1.coord, theV2.coord);
360   }
361
362   Standard_EXPORT void Mirror (const gp_Vec& theV);
363
364   //! Performs the symmetrical transformation of a vector
365   //! with respect to the vector theV which is the center of
366   //! the  symmetry.
367   Standard_NODISCARD Standard_EXPORT gp_Vec Mirrored (const gp_Vec& theV) const;
368
369   Standard_EXPORT void Mirror (const gp_Ax1& theA1);
370
371   //! Performs the symmetrical transformation of a vector
372   //! with respect to an axis placement which is the axis
373   //! of the symmetry.
374   Standard_NODISCARD Standard_EXPORT gp_Vec Mirrored (const gp_Ax1& theA1) const;
375
376   Standard_EXPORT void Mirror (const gp_Ax2& theA2);
377
378   //! Performs the symmetrical transformation of a vector
379   //! with respect to a plane. The axis placement theA2 locates
380   //! the plane of the symmetry : (Location, XDirection, YDirection).
381   Standard_NODISCARD Standard_EXPORT gp_Vec Mirrored (const gp_Ax2& theA2) const;
382
383   void Rotate (const gp_Ax1& theA1, const Standard_Real theAng);
384
385   //! Rotates a vector. theA1 is the axis of the rotation.
386   //! theAng is the angular value of the rotation in radians.
387   Standard_NODISCARD gp_Vec Rotated (const gp_Ax1& theA1, const Standard_Real theAng) const
388   {
389     gp_Vec aVres = *this;
390     aVres.Rotate (theA1, theAng);
391     return aVres;
392   }
393
394   void Scale (const Standard_Real theS) { coord.Multiply (theS); }
395
396   //! Scales a vector. theS is the scaling value.
397   Standard_NODISCARD gp_Vec Scaled (const Standard_Real theS) const
398   {
399     gp_Vec aV = *this;
400     aV.coord.Multiply (theS);
401     return aV;
402   }
403
404   //! Transforms a vector with the transformation theT.
405   Standard_EXPORT void Transform (const gp_Trsf& theT);
406
407   //! Transforms a vector with the transformation theT.
408   Standard_NODISCARD gp_Vec Transformed (const gp_Trsf& theT) const
409   {
410     gp_Vec aV = *this;
411     aV.Transform (theT);
412     return aV;
413   }
414
415   //! Dumps the content of me into the stream
416   Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
417
418 private:
419
420   gp_XYZ coord;
421
422 };
423
424
425 #include <gp.hxx>
426 #include <gp_Dir.hxx>
427 #include <gp_Pnt.hxx>
428 #include <gp_Trsf.hxx>
429
430 //=======================================================================
431 //function :  gp_Vec
432 // purpose :
433 //=======================================================================
434 inline gp_Vec::gp_Vec (const gp_Dir& theV)
435 {
436   coord = theV.XYZ();
437 }
438
439 //=======================================================================
440 //function :  gp_Vec
441 // purpose :
442 //=======================================================================
443 inline gp_Vec::gp_Vec (const gp_Pnt& theP1, const gp_Pnt& theP2)
444 {
445   coord = theP2.XYZ().Subtracted (theP1.XYZ());
446 }
447
448 //=======================================================================
449 //function :  IsNormal
450 // purpose :
451 //=======================================================================
452 inline Standard_Boolean gp_Vec::IsNormal (const gp_Vec& theOther, const Standard_Real theAngularTolerance) const
453 {
454   Standard_Real anAng = M_PI / 2.0 - Angle (theOther);
455   if (anAng < 0)
456   {
457     anAng = -anAng;
458   }
459   return  anAng <= theAngularTolerance;
460 }
461
462 //=======================================================================
463 //function :  Angle
464 // purpose :
465 //=======================================================================
466 inline Standard_Real gp_Vec::Angle (const gp_Vec& theOther) const
467 {
468   gp_VectorWithNullMagnitude_Raise_if (coord.Modulus() <= gp::Resolution() ||
469                                        theOther.coord.Modulus() <= gp::Resolution(), " ");
470   return (gp_Dir (coord)).Angle (theOther);
471 }
472
473 //=======================================================================
474 //function :  AngleWithRef
475 // purpose :
476 //=======================================================================
477 inline Standard_Real gp_Vec::AngleWithRef (const gp_Vec& theOther, const gp_Vec& theVRef) const
478 {
479   gp_VectorWithNullMagnitude_Raise_if (coord.Modulus() <= gp::Resolution() ||
480                                        theVRef.coord.Modulus() <= gp::Resolution() ||
481                                        theOther.coord.Modulus() <= gp::Resolution(), " ");
482   return (gp_Dir (coord)).AngleWithRef (theOther, theVRef);
483 }
484
485 //=======================================================================
486 //function :  Normalized
487 // purpose :
488 //=======================================================================
489 inline gp_Vec gp_Vec::Normalized() const
490 {
491   Standard_Real aD = coord.Modulus();
492   Standard_ConstructionError_Raise_if (aD <= gp::Resolution(), "gp_Vec::Normalized() - vector has zero norm");
493   gp_Vec aV = *this;
494   aV.coord.Divide (aD);
495   return aV;
496 }
497
498 //=======================================================================
499 //function :  Rotate
500 // purpose :
501 //=======================================================================
502 inline void gp_Vec::Rotate (const gp_Ax1& theA1, const Standard_Real theAng)
503 {
504   gp_Trsf aT;
505   aT.SetRotation (theA1, theAng);
506   coord.Multiply (aT.VectorialPart());
507 }
508
509 //=======================================================================
510 //function :  operator*
511 // purpose :
512 //=======================================================================
513 inline gp_Vec operator* (const Standard_Real theScalar, const gp_Vec& theV)
514 {
515   return theV.Multiplied(theScalar);
516 }
517
518 #endif // _gp_Vec_HeaderFile