0032137: Coding Rules - merge redundant .lxx files into header files within Package gp
[occt.git] / src / gp / gp_XYZ.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_XYZ_HeaderFile
16 #define _gp_XYZ_HeaderFile
17
18 #include <gp.hxx>
19 #include <gp_Mat.hxx>
20 #include <Standard_ConstructionError.hxx>
21 #include <Standard_OutOfRange.hxx>
22 #include <Standard_OStream.hxx>
23 #include <Standard_SStream.hxx>
24
25 //! This class describes a cartesian coordinate entity in
26 //! 3D space {X,Y,Z}. This entity is used for algebraic
27 //! calculation. This entity can be transformed
28 //! with a "Trsf" or a  "GTrsf" from package "gp".
29 //! It is used in vectorial computations or for holding this type
30 //! of information in data structures.
31 class gp_XYZ 
32 {
33 public:
34
35   DEFINE_STANDARD_ALLOC
36
37   //! Creates an XYZ object with zero coordinates (0,0,0)
38   gp_XYZ()
39   : x (0.),
40     y (0.),
41     z (0.)
42   {}
43
44   //! creates an XYZ with given coordinates
45   gp_XYZ (const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ)
46   : x (theX),
47     y (theY),
48     z (theZ)
49   {}
50
51   //! For this XYZ object, assigns
52   //! the values theX, theY and theZ to its three coordinates
53   void SetCoord (const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ)
54   {
55     x = theX;
56     y = theY;
57     z = theZ;
58   }
59
60   //! modifies the coordinate of range theIndex
61   //! theIndex = 1 => X is modified
62   //! theIndex = 2 => Y is modified
63   //! theIndex = 3 => Z is modified
64   //! Raises OutOfRange if theIndex != {1, 2, 3}.
65   void SetCoord (const Standard_Integer theIndex, const Standard_Real theXi)
66   {
67     Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > 3, NULL);
68     (&x)[theIndex - 1] = theXi;
69   }
70
71   //! Assigns the given value to the X coordinate
72   void SetX (const Standard_Real theX) { x = theX; }
73
74   //! Assigns the given value to the Y coordinate
75   void SetY (const Standard_Real theY) { y = theY; }
76
77   //! Assigns the given value to the Z coordinate
78   void SetZ (const Standard_Real theZ) { z = theZ; }
79
80   //! returns the coordinate of range theIndex :
81   //! theIndex = 1 => X is returned
82   //! theIndex = 2 => Y is returned
83   //! theIndex = 3 => Z is returned
84   //!
85   //! Raises OutOfRange if theIndex != {1, 2, 3}.
86   Standard_Real Coord (const Standard_Integer theIndex) const
87   {
88     Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > 3, NULL);
89     return (&x)[theIndex - 1];
90   }
91
92   Standard_Real& ChangeCoord (const Standard_Integer theIndex)
93   {
94     Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > 3, NULL);
95     return (&x)[theIndex - 1];
96   }
97
98   void Coord (Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ) const
99   {
100     theX = x;
101     theY = y;
102     theZ = z;
103   }
104
105   //! Returns a const ptr to coordinates location.
106   //! Is useful for algorithms, but DOES NOT PERFORM
107   //! ANY CHECKS!
108   const Standard_Real* GetData() const { return (&x); }
109
110   //! Returns a ptr to coordinates location.
111   //! Is useful for algorithms, but DOES NOT PERFORM
112   //! ANY CHECKS!
113   Standard_Real* ChangeData() { return (&x); }
114
115   //! Returns the X coordinate
116   Standard_Real X() const { return x; }
117
118   //! Returns the Y coordinate
119   Standard_Real Y() const { return y; }
120
121   //! Returns the Z coordinate
122   Standard_Real Z() const { return z; }
123
124   //! computes Sqrt (X*X + Y*Y + Z*Z) where X, Y and Z are the three coordinates of this XYZ object.
125   Standard_Real Modulus() const { return sqrt (x * x + y * y + z * z); }
126
127   //! Computes X*X + Y*Y + Z*Z where X, Y and Z are the three coordinates of this XYZ object.
128   Standard_Real SquareModulus() const { return (x * x + y * y + z * z); }
129
130   //! Returns True if he coordinates of this XYZ object are
131   //! equal to the respective coordinates Other,
132   //! within the specified tolerance theTolerance. I.e.:
133   //! abs(<me>.X() - theOther.X()) <= theTolerance and
134   //! abs(<me>.Y() - theOther.Y()) <= theTolerance and
135   //! abs(<me>.Z() - theOther.Z()) <= theTolerance.
136   Standard_EXPORT Standard_Boolean IsEqual (const gp_XYZ& theOther, const Standard_Real theTolerance) const;
137
138   //! @code
139   //! <me>.X() = <me>.X() + theOther.X()
140   //! <me>.Y() = <me>.Y() + theOther.Y()
141   //! <me>.Z() = <me>.Z() + theOther.Z()
142   void Add (const gp_XYZ& theOther)
143   {
144     x += theOther.x;
145     y += theOther.y;
146     z += theOther.z;
147   }
148
149   void operator+= (const gp_XYZ& theOther) { Add (theOther); }
150
151   //! @code
152   //! new.X() = <me>.X() + theOther.X()
153   //! new.Y() = <me>.Y() + theOther.Y()
154   //! new.Z() = <me>.Z() + theOther.Z()
155   //! @endcode
156   Standard_NODISCARD gp_XYZ Added (const gp_XYZ& theOther) const
157   {
158     return gp_XYZ (x + theOther.x, y + theOther.y, z + theOther.z);
159   }
160
161   Standard_NODISCARD gp_XYZ operator + (const gp_XYZ& theOther) const { return Added (theOther); }
162
163   //! @code
164   //! <me>.X() = <me>.Y() * theOther.Z() - <me>.Z() * theOther.Y()
165   //! <me>.Y() = <me>.Z() * theOther.X() - <me>.X() * theOther.Z()
166   //! <me>.Z() = <me>.X() * theOther.Y() - <me>.Y() * theOther.X()
167   void Cross (const gp_XYZ& theOther);
168
169   void operator^= (const gp_XYZ& theOther) { Cross (theOther); }
170
171   //! @code
172   //! new.X() = <me>.Y() * theOther.Z() - <me>.Z() * theOther.Y()
173   //! new.Y() = <me>.Z() * theOther.X() - <me>.X() * theOther.Z()
174   //! new.Z() = <me>.X() * theOther.Y() - <me>.Y() * theOther.X()
175   //! @endcode
176   Standard_NODISCARD gp_XYZ Crossed (const gp_XYZ& theOther) const
177   {
178     return gp_XYZ (y * theOther.z - z * theOther.y,
179                    z * theOther.x - x * theOther.z,
180                    x * theOther.y - y * theOther.x);
181   }
182
183   Standard_NODISCARD gp_XYZ operator ^ (const gp_XYZ& theOther) const { return Crossed (theOther); }
184
185   //! Computes the magnitude of the cross product between <me> and
186   //! theRight. Returns || <me> ^ theRight ||
187   Standard_Real CrossMagnitude (const gp_XYZ& theRight) const;
188
189   //! Computes the square magnitude of the cross product between <me> and
190   //! theRight. Returns || <me> ^ theRight ||**2
191   Standard_Real CrossSquareMagnitude (const gp_XYZ& theRight) const;
192
193   //! Triple vector product
194   //! Computes <me> = <me>.Cross(theCoord1.Cross(theCoord2))
195   void CrossCross (const gp_XYZ& theCoord1, const gp_XYZ& theCoord2);
196
197   //! Triple vector product
198   //! computes New = <me>.Cross(theCoord1.Cross(theCoord2))
199   Standard_NODISCARD gp_XYZ CrossCrossed (const gp_XYZ& theCoord1, const gp_XYZ& theCoord2) const
200   {
201     gp_XYZ aCoord0 = *this;
202     aCoord0.CrossCross (theCoord1, theCoord2);
203     return aCoord0;
204   }
205
206   //! divides <me> by a real.
207   void Divide (const Standard_Real theScalar)
208   {
209     x /= theScalar;
210     y /= theScalar;
211     z /= theScalar;
212   }
213
214   void operator/= (const Standard_Real theScalar) { Divide (theScalar); }
215
216   //! divides <me> by a real.
217   Standard_NODISCARD gp_XYZ Divided (const Standard_Real theScalar) const { return gp_XYZ (x / theScalar, y / theScalar, z / theScalar); }
218
219   Standard_NODISCARD gp_XYZ operator/ (const Standard_Real theScalar) const { return Divided (theScalar); }
220
221   //! computes the scalar product between <me> and theOther
222   Standard_Real Dot (const gp_XYZ& theOther) const { return(x * theOther.x + y * theOther.y + z * theOther.z); }
223
224   Standard_Real operator* (const gp_XYZ& theOther) const { return Dot (theOther); }
225
226   //! computes the triple scalar product
227   Standard_Real DotCross (const gp_XYZ& theCoord1, const gp_XYZ& theCoord2) const;
228
229   //! @code
230   //! <me>.X() = <me>.X() * theScalar;
231   //! <me>.Y() = <me>.Y() * theScalar;
232   //! <me>.Z() = <me>.Z() * theScalar;
233   void Multiply (const Standard_Real theScalar)
234   {
235     x *= theScalar;
236     y *= theScalar;
237     z *= theScalar;
238   }
239
240   void operator*= (const Standard_Real theScalar) { Multiply (theScalar); }
241
242   //! @code
243   //! <me>.X() = <me>.X() * theOther.X();
244   //! <me>.Y() = <me>.Y() * theOther.Y();
245   //! <me>.Z() = <me>.Z() * theOther.Z();
246   void Multiply (const gp_XYZ& theOther)
247   {
248     x *= theOther.x;
249     y *= theOther.y;
250     z *= theOther.z;
251   }
252
253   void operator*= (const gp_XYZ& theOther) { Multiply (theOther); }
254
255   //! <me> = theMatrix * <me>
256   void Multiply (const gp_Mat& theMatrix);
257
258   void operator*= (const gp_Mat& theMatrix) { Multiply (theMatrix); }
259
260   //! @code
261   //! New.X() = <me>.X() * theScalar;
262   //! New.Y() = <me>.Y() * theScalar;
263   //! New.Z() = <me>.Z() * theScalar;
264   Standard_NODISCARD gp_XYZ Multiplied (const Standard_Real theScalar) const { return gp_XYZ (x * theScalar, y * theScalar, z * theScalar); }
265
266   Standard_NODISCARD gp_XYZ operator* (const Standard_Real theScalar) const { return Multiplied (theScalar); }
267
268   //! @code
269   //! new.X() = <me>.X() * theOther.X();
270   //! new.Y() = <me>.Y() * theOther.Y();
271   //! new.Z() = <me>.Z() * theOther.Z();
272   Standard_NODISCARD gp_XYZ Multiplied (const gp_XYZ& theOther) const { return gp_XYZ (x * theOther.x, y * theOther.y, z * theOther.z); }
273
274   //! New = theMatrix * <me>
275   //! @endcode
276   Standard_NODISCARD gp_XYZ Multiplied (const gp_Mat& theMatrix) const
277   {
278     return gp_XYZ (theMatrix.Value (1, 1) * x + theMatrix.Value (1, 2) * y + theMatrix.Value (1, 3) * z,
279                    theMatrix.Value (2, 1) * x + theMatrix.Value (2, 2) * y + theMatrix.Value (2, 3) * z,
280                    theMatrix.Value (3, 1) * x + theMatrix.Value (3, 2) * y + theMatrix.Value (3, 3) * z);
281   }
282
283   Standard_NODISCARD gp_XYZ operator* (const gp_Mat& theMatrix) const { return Multiplied (theMatrix); }
284
285   //! @code
286   //! <me>.X() = <me>.X()/ <me>.Modulus()
287   //! <me>.Y() = <me>.Y()/ <me>.Modulus()
288   //! <me>.Z() = <me>.Z()/ <me>.Modulus()
289   //! @endcode
290   //! Raised if <me>.Modulus() <= Resolution from gp
291   void Normalize();
292
293   //! @code
294   //! New.X() = <me>.X()/ <me>.Modulus()
295   //! New.Y() = <me>.Y()/ <me>.Modulus()
296   //! New.Z() = <me>.Z()/ <me>.Modulus()
297   //! @endcode
298   //! Raised if <me>.Modulus() <= Resolution from gp
299   Standard_NODISCARD gp_XYZ Normalized() const
300   {
301     Standard_Real aD = Modulus();
302     Standard_ConstructionError_Raise_if (aD <= gp::Resolution(), "gp_XYZ::Normalized() - vector has zero norm");
303     return gp_XYZ(x / aD, y / aD, z / aD);
304   }
305
306   //! @code
307   //! <me>.X() = -<me>.X()
308   //! <me>.Y() = -<me>.Y()
309   //! <me>.Z() = -<me>.Z()
310   void Reverse()
311   {
312     x = -x;
313     y = -y;
314     z = -z;
315   }
316
317   //! @code
318   //! New.X() = -<me>.X()
319   //! New.Y() = -<me>.Y()
320   //! New.Z() = -<me>.Z()
321   Standard_NODISCARD gp_XYZ Reversed() const { return gp_XYZ (-x, -y, -z); }
322
323   //! @code
324   //! <me>.X() = <me>.X() - theOther.X()
325   //! <me>.Y() = <me>.Y() - theOther.Y()
326   //! <me>.Z() = <me>.Z() - theOther.Z()
327   void Subtract (const gp_XYZ& theOther)
328   {
329     x -= theOther.x;
330     y -= theOther.y;
331     z -= theOther.z;
332   }
333
334   void operator-= (const gp_XYZ& theOther) { Subtract (theOther); }
335
336   //! @code
337   //! new.X() = <me>.X() - theOther.X()
338   //! new.Y() = <me>.Y() - theOther.Y()
339   //! new.Z() = <me>.Z() - theOther.Z()
340   Standard_NODISCARD gp_XYZ Subtracted (const gp_XYZ& theOther) const { return gp_XYZ (x - theOther.x, y - theOther.y, z - theOther.z); }
341
342   Standard_NODISCARD gp_XYZ operator-  (const gp_XYZ& theOther) const { return Subtracted (theOther); }
343
344   //! <me> is set to the following linear form :
345   //! @code
346   //! theA1 * theXYZ1 + theA2 * theXYZ2 + theA3 * theXYZ3 + theXYZ4
347   void SetLinearForm (const Standard_Real theA1, const gp_XYZ& theXYZ1,
348                       const Standard_Real theA2, const gp_XYZ& theXYZ2,
349                       const Standard_Real theA3, const gp_XYZ& theXYZ3,
350                       const gp_XYZ& theXYZ4)
351   {
352     x = theA1 * theXYZ1.x + theA2 * theXYZ2.x + theA3 * theXYZ3.x + theXYZ4.x;
353     y = theA1 * theXYZ1.y + theA2 * theXYZ2.y + theA3 * theXYZ3.y + theXYZ4.y;
354     z = theA1 * theXYZ1.z + theA2 * theXYZ2.z + theA3 * theXYZ3.z + theXYZ4.z;
355   }
356
357   //! <me> is set to the following linear form :
358   //! @code
359   //! theA1 * theXYZ1 + theA2 * theXYZ2 + theA3 * theXYZ3
360   void SetLinearForm (const Standard_Real theA1, const gp_XYZ& theXYZ1,
361                       const Standard_Real theA2, const gp_XYZ& theXYZ2,
362                       const Standard_Real theA3, const gp_XYZ& theXYZ3)
363   {
364     x = theA1 * theXYZ1.x + theA2 * theXYZ2.x + theA3 * theXYZ3.x;
365     y = theA1 * theXYZ1.y + theA2 * theXYZ2.y + theA3 * theXYZ3.y;
366     z = theA1 * theXYZ1.z + theA2 * theXYZ2.z + theA3 * theXYZ3.z;
367   }
368
369   //! <me> is set to the following linear form :
370   //! @code
371   //! theA1 * theXYZ1 + theA2 * theXYZ2 + theXYZ3
372   void SetLinearForm (const Standard_Real theA1, const gp_XYZ& theXYZ1,
373                       const Standard_Real theA2, const gp_XYZ& theXYZ2,
374                       const gp_XYZ& theXYZ3)
375   {
376     x = theA1 * theXYZ1.x + theA2 * theXYZ2.x + theXYZ3.x;
377     y = theA1 * theXYZ1.y + theA2 * theXYZ2.y + theXYZ3.y;
378     z = theA1 * theXYZ1.z + theA2 * theXYZ2.z + theXYZ3.z;
379   }
380
381   //! <me> is set to the following linear form :
382   //! @code
383   //! theA1 * theXYZ1 + theA2 * theXYZ2
384   void SetLinearForm (const Standard_Real theA1, const gp_XYZ& theXYZ1,
385                       const Standard_Real theA2, const gp_XYZ& theXYZ2)
386   {
387     x = theA1 * theXYZ1.x + theA2 * theXYZ2.x;
388     y = theA1 * theXYZ1.y + theA2 * theXYZ2.y;
389     z = theA1 * theXYZ1.z + theA2 * theXYZ2.z;
390   }
391
392   //! <me> is set to the following linear form :
393   //! @code
394   //! theA1 * theXYZ1 + theXYZ2
395   void SetLinearForm (const Standard_Real theA1, const gp_XYZ& theXYZ1,
396                       const gp_XYZ& theXYZ2)
397   {
398     x = theA1 * theXYZ1.x + theXYZ2.x;
399     y = theA1 * theXYZ1.y + theXYZ2.y;
400     z = theA1 * theXYZ1.z + theXYZ2.z;
401   }
402
403   //! <me> is set to the following linear form :
404   //! @code
405   //! theXYZ1 + theXYZ2
406   void SetLinearForm (const gp_XYZ& theXYZ1, const gp_XYZ& theXYZ2)
407   {
408     x = theXYZ1.x + theXYZ2.x;
409     y = theXYZ1.y + theXYZ2.y;
410     z = theXYZ1.z + theXYZ2.z;
411   }
412
413   //! Dumps the content of me into the stream
414   Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
415
416   //! Inits the content of me from the stream
417   Standard_EXPORT Standard_Boolean InitFromJson (const Standard_SStream& theSStream, Standard_Integer& theStreamPos);
418
419 private:
420
421   Standard_Real x;
422   Standard_Real y;
423   Standard_Real z;
424
425 };
426
427 //=======================================================================
428 //function : Cross
429 // purpose :
430 //=======================================================================
431 inline void gp_XYZ::Cross (const gp_XYZ& theRight)
432 {
433   Standard_Real aXresult = y * theRight.z - z * theRight.y;
434   Standard_Real aYresult = z * theRight.x - x * theRight.z;
435   z = x * theRight.y - y * theRight.x;
436   x = aXresult;
437   y = aYresult;
438 }
439
440 //=======================================================================
441 //function : CrossMagnitude
442 // purpose :
443 //=======================================================================
444 inline Standard_Real gp_XYZ::CrossMagnitude (const gp_XYZ& theRight) const
445 {
446   Standard_Real aXresult = y * theRight.z - z * theRight.y;
447   Standard_Real aYresult = z * theRight.x - x * theRight.z;
448   Standard_Real aZresult = x * theRight.y - y * theRight.x;
449   return sqrt (aXresult * aXresult + aYresult * aYresult + aZresult * aZresult);
450 }
451
452 //=======================================================================
453 //function : CrossSquareMagnitude
454 // purpose :
455 //=======================================================================
456 inline Standard_Real gp_XYZ::CrossSquareMagnitude (const gp_XYZ& theRight) const
457 {
458   Standard_Real aXresult = y * theRight.z - z * theRight.y;
459   Standard_Real aYresult = z * theRight.x - x * theRight.z;
460   Standard_Real aZresult = x * theRight.y - y * theRight.x;
461   return aXresult * aXresult + aYresult * aYresult + aZresult * aZresult;
462 }
463
464 //=======================================================================
465 //function : CrossCross
466 // purpose :
467 //=======================================================================
468 inline void gp_XYZ::CrossCross (const gp_XYZ& theCoord1, const gp_XYZ& theCoord2)
469 {
470   Standard_Real aXresult = y * (theCoord1.x * theCoord2.y - theCoord1.y * theCoord2.x) -
471                            z * (theCoord1.z * theCoord2.x - theCoord1.x * theCoord2.z);
472   Standard_Real anYresult = z * (theCoord1.y * theCoord2.z - theCoord1.z * theCoord2.y) -
473                             x * (theCoord1.x * theCoord2.y - theCoord1.y * theCoord2.x);
474   z = x * (theCoord1.z * theCoord2.x - theCoord1.x * theCoord2.z) -
475       y * (theCoord1.y * theCoord2.z - theCoord1.z * theCoord2.y);
476   x = aXresult;
477   y = anYresult;
478 }
479
480 //=======================================================================
481 //function : DotCross
482 // purpose :
483 //=======================================================================
484 inline Standard_Real gp_XYZ::DotCross (const gp_XYZ& theCoord1, const gp_XYZ& theCoord2) const
485 {
486   Standard_Real aXresult = theCoord1.y * theCoord2.z - theCoord1.z * theCoord2.y;
487   Standard_Real anYresult = theCoord1.z * theCoord2.x - theCoord1.x * theCoord2.z;
488   Standard_Real aZresult = theCoord1.x * theCoord2.y - theCoord1.y * theCoord2.x;
489   return (x * aXresult + y * anYresult + z * aZresult);
490 }
491
492 //=======================================================================
493 //function : Multiply
494 // purpose :
495 //=======================================================================
496 inline void gp_XYZ::Multiply (const gp_Mat& theMatrix)
497 {
498   Standard_Real aXresult = theMatrix.Value (1, 1) * x + theMatrix.Value (1, 2) * y + theMatrix.Value (1, 3) * z;
499   Standard_Real anYresult = theMatrix.Value (2, 1) * x + theMatrix.Value (2, 2) * y + theMatrix.Value (2, 3) * z;
500   z = theMatrix.Value (3, 1) * x + theMatrix.Value (3, 2) * y + theMatrix.Value (3, 3) * z;
501   x = aXresult;
502   y = anYresult;
503 }
504
505 //=======================================================================
506 //function : Normalize
507 // purpose :
508 //=======================================================================
509 inline void gp_XYZ::Normalize()
510 {
511   Standard_Real aD = Modulus();
512   Standard_ConstructionError_Raise_if (aD <= gp::Resolution(), "gp_XYZ::Normalize() - vector has zero norm");
513   x = x / aD;
514   y = y / aD;
515   z = z / aD;
516 }
517
518 //=======================================================================
519 //function : operator*
520 // purpose :
521 //=======================================================================
522 inline gp_XYZ operator* (const gp_Mat& theMatrix, const gp_XYZ& theCoord1)
523 {
524   return theCoord1.Multiplied (theMatrix);
525 }
526
527 //=======================================================================
528 //function : operator*
529 // purpose :
530 //=======================================================================
531 inline gp_XYZ operator* (const Standard_Real theScalar, const gp_XYZ& theCoord1)
532 {
533   return theCoord1.Multiplied (theScalar);
534 }
535
536 #endif // _gp_XYZ_HeaderFile