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_Vec2d_HeaderFile
16 #define _gp_Vec2d_HeaderFile
17 
18 #include <gp_VectorWithNullMagnitude.hxx>
19 #include <gp_XY.hxx>
20 #include <Standard_ConstructionError.hxx>
21 #include <Standard_OutOfRange.hxx>
22 
23 class gp_Dir2d;
24 class gp_Pnt2d;
25 class gp_Ax2d;
26 class gp_Trsf2d;
27 
28 //! Defines a non-persistent vector in 2D space.
29 class gp_Vec2d
30 {
31 public:
32 
33   DEFINE_STANDARD_ALLOC
34 
35   //! Creates a zero vector.
gp_Vec2d()36   gp_Vec2d() {}
37 
38   //! Creates a unitary vector from a direction theV.
39   gp_Vec2d (const gp_Dir2d& theV);
40 
41   //! Creates a vector with a doublet of coordinates.
gp_Vec2d(const gp_XY & theCoord)42   gp_Vec2d (const gp_XY& theCoord)
43     : coord(theCoord)
44   {}
45 
46   //! Creates a point with its two Cartesian coordinates.
gp_Vec2d(const Standard_Real theXv,const Standard_Real theYv)47   gp_Vec2d (const Standard_Real theXv, const Standard_Real theYv)
48   : coord (theXv, theYv)
49   {}
50 
51   //! Creates a vector from two points. The length of the vector
52   //! is the distance between theP1 and theP2
53   gp_Vec2d (const gp_Pnt2d& theP1, const gp_Pnt2d& theP2);
54 
55   //! Changes the coordinate of range theIndex
56   //! theIndex = 1 => X is modified
57   //! theIndex = 2 => Y is modified
58   //! Raises OutOfRange if theIndex != {1, 2}.
SetCoord(const Standard_Integer theIndex,const Standard_Real theXi)59   void SetCoord (const Standard_Integer theIndex, const Standard_Real theXi) { coord.SetCoord (theIndex, theXi); }
60 
61   //! For this vector, assigns
62   //! the values theXv and theYv to its two coordinates
SetCoord(const Standard_Real theXv,const Standard_Real theYv)63   void SetCoord (const Standard_Real theXv, const Standard_Real theYv) { coord.SetCoord (theXv, theYv); }
64 
65   //! Assigns the given value to the X coordinate of this vector.
SetX(const Standard_Real theX)66   void SetX (const Standard_Real theX) { coord.SetX (theX); }
67 
68   //! Assigns the given value to the Y coordinate of this vector.
SetY(const Standard_Real theY)69   void SetY (const Standard_Real theY) { coord.SetY (theY); }
70 
71   //! Assigns the two coordinates of theCoord to this vector.
SetXY(const gp_XY & theCoord)72   void SetXY (const gp_XY& theCoord) { coord = theCoord; }
73 
74   //! Returns the coordinate of range theIndex :
75   //! theIndex = 1 => X is returned
76   //! theIndex = 2 => Y is returned
77   //! Raised if theIndex != {1, 2}.
Coord(const Standard_Integer theIndex) const78   Standard_Real Coord (const Standard_Integer theIndex) const { return coord.Coord (theIndex); }
79 
80   //! For this vector, returns  its two coordinates theXv and theYv
Coord(Standard_Real & theXv,Standard_Real & theYv) const81   void Coord (Standard_Real& theXv, Standard_Real& theYv) const { coord.Coord (theXv, theYv); }
82 
83   //! For this vector, returns its X  coordinate.
X() const84   Standard_Real X() const { return coord.X(); }
85 
86   //! For this vector, returns its Y  coordinate.
Y() const87   Standard_Real Y() const { return coord.Y(); }
88 
89   //! For this vector, returns its two coordinates as a number pair
XY() const90   const gp_XY& XY() const { return coord; }
91 
92   //! Returns True if the two vectors have the same magnitude value
93   //! and the same direction. The precision values are theLinearTolerance
94   //! for the magnitude and theAngularTolerance for the direction.
95   Standard_EXPORT Standard_Boolean IsEqual (const gp_Vec2d& theOther, const Standard_Real theLinearTolerance, const Standard_Real theAngularTolerance) const;
96 
97   //! Returns True if abs(Abs(<me>.Angle(theOther)) - PI/2.)
98   //! <= theAngularTolerance
99   //! Raises VectorWithNullMagnitude if <me>.Magnitude() <= Resolution or
100   //! theOther.Magnitude() <= Resolution from gp.
IsNormal(const gp_Vec2d & theOther,const Standard_Real theAngularTolerance) const101   Standard_Boolean IsNormal (const gp_Vec2d& theOther, const Standard_Real theAngularTolerance) const
102   {
103     const Standard_Real anAng = Abs (M_PI_2 - Abs (Angle (theOther)));
104     return !(anAng > theAngularTolerance);
105   }
106 
107   //! Returns True if PI - Abs(<me>.Angle(theOther)) <= theAngularTolerance
108   //! Raises VectorWithNullMagnitude if <me>.Magnitude() <= Resolution or
109   //! theOther.Magnitude() <= Resolution from gp.
110   Standard_Boolean IsOpposite (const gp_Vec2d& theOther, const Standard_Real theAngularTolerance) const;
111 
112   //! Returns true if Abs(Angle(<me>, theOther)) <= theAngularTolerance or
113   //! PI - Abs(Angle(<me>, theOther)) <= theAngularTolerance
114   //! Two vectors with opposite directions are considered as parallel.
115   //! Raises VectorWithNullMagnitude if <me>.Magnitude() <= Resolution or
116   //! theOther.Magnitude() <= Resolution from gp
117   Standard_Boolean IsParallel (const gp_Vec2d& theOther, const Standard_Real theAngularTolerance) const;
118 
119   //! Computes the angular value between <me> and <theOther>
120   //! returns the angle value between -PI and PI in radian.
121   //! The orientation is from <me> to theOther. The positive sense is the
122   //! trigonometric sense.
123   //! Raises VectorWithNullMagnitude if <me>.Magnitude() <= Resolution from gp or
124   //! theOther.Magnitude() <= Resolution because the angular value is
125   //! indefinite if one of the vectors has a null magnitude.
126   Standard_EXPORT Standard_Real Angle (const gp_Vec2d& theOther) const;
127 
128   //! Computes the magnitude of this vector.
Magnitude() const129   Standard_Real Magnitude() const { return coord.Modulus(); }
130 
131   //! Computes the square magnitude of this vector.
SquareMagnitude() const132   Standard_Real SquareMagnitude() const { return coord.SquareModulus(); }
133 
Add(const gp_Vec2d & theOther)134   void Add (const gp_Vec2d& theOther) { coord.Add (theOther.coord); }
135 
operator +=(const gp_Vec2d & theOther)136   void operator += (const gp_Vec2d& theOther) { Add (theOther); }
137 
138   //! Adds two vectors
Added(const gp_Vec2d & theOther) const139   Standard_NODISCARD gp_Vec2d Added (const gp_Vec2d& theOther) const
140   {
141     gp_Vec2d aV = *this;
142     aV.coord.Add (theOther.coord);
143     return aV;
144   }
145 
operator +(const gp_Vec2d & theOther) const146   Standard_NODISCARD gp_Vec2d operator + (const gp_Vec2d& theOther) const { return Added (theOther); }
147 
148   //! Computes the crossing product between two vectors
Crossed(const gp_Vec2d & theRight) const149   Standard_NODISCARD Standard_Real Crossed (const gp_Vec2d& theRight) const
150   {
151     return coord.Crossed (theRight.coord);
152   }
153 
operator ^(const gp_Vec2d & theRight) const154   Standard_NODISCARD Standard_Real operator ^ (const gp_Vec2d& theRight) const { return Crossed (theRight); }
155 
156   //! Computes the magnitude of the cross product between <me> and
157   //! theRight. Returns || <me> ^ theRight ||
CrossMagnitude(const gp_Vec2d & theRight) const158   Standard_Real CrossMagnitude (const gp_Vec2d& theRight) const
159   {
160     return coord.CrossMagnitude (theRight.coord);
161   }
162 
163   //! Computes the square magnitude of the cross product between <me> and
164   //! theRight. Returns || <me> ^ theRight ||**2
CrossSquareMagnitude(const gp_Vec2d & theRight) const165   Standard_Real CrossSquareMagnitude (const gp_Vec2d& theRight) const
166   {
167     return coord.CrossSquareMagnitude (theRight.coord);
168   }
169 
Divide(const Standard_Real theScalar)170   void Divide (const Standard_Real theScalar) { coord.Divide (theScalar); }
171 
operator /=(const Standard_Real theScalar)172   void operator /= (const Standard_Real theScalar) { Divide (theScalar); }
173 
174   //! divides a vector by a scalar
Divided(const Standard_Real theScalar) const175   Standard_NODISCARD gp_Vec2d Divided (const Standard_Real theScalar) const
176   {
177     gp_Vec2d aV = *this;
178     aV.coord.Divide (theScalar);
179     return aV;
180   }
181 
operator /(const Standard_Real theScalar) const182   Standard_NODISCARD gp_Vec2d operator / (const Standard_Real theScalar) const { return Divided (theScalar); }
183 
184   //! Computes the scalar product
Dot(const gp_Vec2d & theOther) const185   Standard_Real Dot (const gp_Vec2d& theOther) const { return coord.Dot (theOther.coord); }
186 
operator *(const gp_Vec2d & theOther) const187   Standard_Real operator * (const gp_Vec2d& theOther) const { return Dot (theOther); }
188 
GetNormal() const189   gp_Vec2d GetNormal() const { return gp_Vec2d (this->Y(), (-1)*this->X()); }
190 
Multiply(const Standard_Real theScalar)191   void Multiply (const Standard_Real theScalar) { coord.Multiply (theScalar); }
192 
operator *=(const Standard_Real theScalar)193   void operator *= (const Standard_Real theScalar) { Multiply (theScalar); }
194 
195   //! Normalizes a vector
196   //! Raises an exception if the magnitude of the vector is
197   //! lower or equal to Resolution from package gp.
Multiplied(const Standard_Real theScalar) const198   Standard_NODISCARD gp_Vec2d Multiplied (const Standard_Real theScalar) const
199   {
200     gp_Vec2d aV = *this;
201     aV.coord.Multiply (theScalar);
202     return aV;
203   }
204 
operator *(const Standard_Real theScalar) const205   Standard_NODISCARD gp_Vec2d operator * (const Standard_Real theScalar) const { return Multiplied (theScalar); }
206 
Normalize()207   void Normalize()
208   {
209     Standard_Real aD = coord.Modulus();
210     Standard_ConstructionError_Raise_if (aD <= gp::Resolution(), "gp_Vec2d::Normalize() - vector has zero norm");
211     coord.Divide (aD);
212   }
213 
214   //! Normalizes a vector
215   //! Raises an exception if the magnitude of the vector is
216   //! lower or equal to Resolution from package gp.
217   //! Reverses the direction of a vector
218   Standard_NODISCARD gp_Vec2d Normalized() const;
219 
Reverse()220   void Reverse() { coord.Reverse(); }
221 
222   //! Reverses the direction of a vector
Reversed() const223   Standard_NODISCARD gp_Vec2d Reversed() const
224   {
225     gp_Vec2d aV = *this;
226     aV.coord.Reverse();
227     return aV;
228   }
229 
operator -() const230   Standard_NODISCARD gp_Vec2d operator -() const { return Reversed(); }
231 
232   //! Subtracts two vectors
Subtract(const gp_Vec2d & theRight)233   void Subtract (const gp_Vec2d& theRight)
234   {
235     coord.Subtract (theRight.coord);
236   }
237 
operator -=(const gp_Vec2d & theRight)238   void operator -= (const gp_Vec2d& theRight) { Subtract (theRight); }
239 
240   //! Subtracts two vectors
Subtracted(const gp_Vec2d & theRight) const241   Standard_NODISCARD gp_Vec2d Subtracted (const gp_Vec2d& theRight) const
242   {
243     gp_Vec2d aV = *this;
244     aV.coord.Subtract (theRight.coord);
245     return aV;
246   }
247 
operator -(const gp_Vec2d & theRight) const248   Standard_NODISCARD gp_Vec2d operator - (const gp_Vec2d& theRight) const { return Subtracted (theRight); }
249 
250   //! <me> is set to the following linear form :
251   //! theA1 * theV1 + theA2 * theV2 + theV3
SetLinearForm(const Standard_Real theA1,const gp_Vec2d & theV1,const Standard_Real theA2,const gp_Vec2d & theV2,const gp_Vec2d & theV3)252   void SetLinearForm (const Standard_Real theA1, const gp_Vec2d& theV1,
253                       const Standard_Real theA2, const gp_Vec2d& theV2, const gp_Vec2d& theV3)
254   {
255     coord.SetLinearForm (theA1, theV1.coord, theA2, theV2.coord, theV3.coord);
256   }
257 
258   //! <me> is set to the following linear form : theA1 * theV1 + theA2 * theV2
SetLinearForm(const Standard_Real theA1,const gp_Vec2d & theV1,const Standard_Real theA2,const gp_Vec2d & theV2)259   void SetLinearForm (const Standard_Real theA1, const gp_Vec2d& theV1,
260                       const Standard_Real theA2, const gp_Vec2d& theV2)
261   {
262     coord.SetLinearForm (theA1, theV1.coord, theA2, theV2.coord);
263   }
264 
265   //! <me> is set to the following linear form : theA1 * theV1 + theV2
SetLinearForm(const Standard_Real theA1,const gp_Vec2d & theV1,const gp_Vec2d & theV2)266   void SetLinearForm (const Standard_Real theA1, const gp_Vec2d& theV1, const gp_Vec2d& theV2)
267   {
268     coord.SetLinearForm (theA1, theV1.coord, theV2.coord);
269   }
270 
271   //! <me> is set to the following linear form : theV1 + theV2
SetLinearForm(const gp_Vec2d & theV1,const gp_Vec2d & theV2)272   void SetLinearForm (const gp_Vec2d& theV1, const gp_Vec2d& theV2)
273   {
274     coord.SetLinearForm (theV1.coord, theV2.coord);
275   }
276 
277   //! Performs the symmetrical transformation of a vector
278   //! with respect to the vector theV which is the center of
279   //! the  symmetry.
280   Standard_EXPORT void Mirror (const gp_Vec2d& theV);
281 
282   //! Performs the symmetrical transformation of a vector
283   //! with respect to the vector theV which is the center of
284   //! the  symmetry.
285   Standard_NODISCARD Standard_EXPORT gp_Vec2d Mirrored (const gp_Vec2d& theV) const;
286 
287   //! Performs the symmetrical transformation of a vector
288   //! with respect to an axis placement which is the axis
289   //! of the symmetry.
290   Standard_EXPORT void Mirror (const gp_Ax2d& theA1);
291 
292   //! Performs the symmetrical transformation of a vector
293   //! with respect to an axis placement which is the axis
294   //! of the symmetry.
295   Standard_NODISCARD Standard_EXPORT gp_Vec2d Mirrored (const gp_Ax2d& theA1) const;
296 
297   void Rotate (const Standard_Real theAng);
298 
299   //! Rotates a vector. theAng is the angular value of the
300   //! rotation in radians.
Rotated(const Standard_Real theAng) const301   Standard_NODISCARD gp_Vec2d Rotated (const Standard_Real theAng) const
302   {
303     gp_Vec2d aV = *this;
304     aV.Rotate (theAng);
305     return aV;
306   }
307 
Scale(const Standard_Real theS)308   void Scale (const Standard_Real theS) { coord.Multiply (theS); }
309 
310   //! Scales a vector. theS is the scaling value.
Scaled(const Standard_Real theS) const311   Standard_NODISCARD gp_Vec2d Scaled (const Standard_Real theS) const
312   {
313     gp_Vec2d aV = *this;
314     aV.coord.Multiply (theS);
315     return aV;
316   }
317 
318   Standard_EXPORT void Transform (const gp_Trsf2d& theT);
319 
320   //! Transforms a vector with a Trsf from gp.
Transformed(const gp_Trsf2d & theT) const321   Standard_NODISCARD gp_Vec2d Transformed (const gp_Trsf2d& theT) const
322   {
323     gp_Vec2d aV = *this;
324     aV.Transform (theT);
325     return aV;
326   }
327 
328 private:
329 
330   gp_XY coord;
331 
332 };
333 
334 #include <gp_Dir2d.hxx>
335 #include <gp_Trsf2d.hxx>
336 #include <gp_Pnt2d.hxx>
337 
338 //=======================================================================
339 //function :  gp_Vec2d
340 // purpose :
341 //=======================================================================
gp_Vec2d(const gp_Dir2d & theV)342 inline gp_Vec2d::gp_Vec2d (const gp_Dir2d& theV)
343 {
344   coord = theV.XY();
345 }
346 
347 //=======================================================================
348 //function :  gp_Vec2d
349 // purpose :
350 //=======================================================================
gp_Vec2d(const gp_Pnt2d & theP1,const gp_Pnt2d & theP2)351 inline gp_Vec2d::gp_Vec2d (const gp_Pnt2d& theP1, const gp_Pnt2d& theP2)
352 {
353   coord = theP2.XY().Subtracted (theP1.XY());
354 }
355 
356 //=======================================================================
357 //function :  IsOpposite
358 // purpose :
359 //=======================================================================
IsOpposite(const gp_Vec2d & theOther,const Standard_Real theAngularTolerance) const360 inline Standard_Boolean gp_Vec2d::IsOpposite (const gp_Vec2d& theOther, const Standard_Real theAngularTolerance) const
361 {
362   Standard_Real anAng = Angle (theOther);
363   if (anAng < 0)
364   {
365     anAng = -anAng;
366   }
367   return M_PI - anAng <= theAngularTolerance;
368 }
369 
370 //=======================================================================
371 //function :  IsParallel
372 // purpose :
373 //=======================================================================
IsParallel(const gp_Vec2d & theOther,const Standard_Real theAngularTolerance) const374 inline Standard_Boolean gp_Vec2d::IsParallel (const gp_Vec2d& theOther, const Standard_Real theAngularTolerance) const
375 {
376   Standard_Real anAng = Angle (theOther);
377   if (anAng < 0)
378   {
379     anAng = -anAng;
380   }
381   return anAng <= theAngularTolerance || M_PI - anAng <= theAngularTolerance;
382 }
383 
384 //=======================================================================
385 //function :  Normalized
386 // purpose :
387 //=======================================================================
Normalized() const388 inline gp_Vec2d gp_Vec2d::Normalized() const
389 {
390   Standard_Real aD = coord.Modulus();
391   Standard_ConstructionError_Raise_if (aD <= gp::Resolution(), "gp_Vec2d::Normalized() - vector has zero norm");
392   gp_Vec2d aV = *this;
393   aV.coord.Divide (aD);
394   return aV;
395 }
396 
397 //=======================================================================
398 //function :  Rotate
399 // purpose :
400 //=======================================================================
Rotate(const Standard_Real theAng)401 inline void gp_Vec2d::Rotate (const Standard_Real theAng)
402 {
403   gp_Trsf2d aT;
404   aT.SetRotation (gp_Pnt2d(0.0, 0.0), theAng);
405   coord.Multiply (aT.VectorialPart());
406 }
407 
408 //=======================================================================
409 //function :  operator*
410 // purpose :
411 //=======================================================================
operator *(const Standard_Real theScalar,const gp_Vec2d & theV)412 inline gp_Vec2d operator* (const Standard_Real theScalar,
413                            const gp_Vec2d& theV)
414 {
415   return theV.Multiplied (theScalar);
416 }
417 
418 #endif // _gp_Vec2d_HeaderFile
419