0032137: Coding Rules - merge redundant .lxx files into header files within Package gp
[occt.git] / src / gp / gp_Hypr2d.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_Hypr2d_HeaderFile
16 #define _gp_Hypr2d_HeaderFile
17
18 #include <gp.hxx>
19 #include <gp_Ax22d.hxx>
20 #include <gp_Ax2d.hxx>
21 #include <gp_Pnt2d.hxx>
22 #include <Standard_DomainError.hxx>
23 #include <Standard_ConstructionError.hxx>
24
25 //! Describes a branch of a hyperbola in the plane (2D space).
26 //! A hyperbola is defined by its major and minor radii, and
27 //! positioned in the plane with a coordinate system (a
28 //! gp_Ax22d object) of which:
29 //! -   the origin is the center of the hyperbola,
30 //! -   the "X Direction" defines the major axis of the hyperbola, and
31 //! -   the "Y Direction" defines the minor axis of the hyperbola.
32 //! This coordinate system is the "local coordinate system"
33 //! of the hyperbola. The orientation of this coordinate
34 //! system (direct or indirect) gives an implicit orientation to
35 //! the hyperbola. In this coordinate system, the equation of
36 //! the hyperbola is:
37 //! X*X/(MajorRadius**2)-Y*Y/(MinorRadius**2) = 1.0
38 //! The branch of the hyperbola described is the one located
39 //! on the positive side of the major axis.
40 //! The following schema shows the plane of the hyperbola,
41 //! and in it, the respective positions of the three branches of
42 //! hyperbolas constructed with the functions OtherBranch,
43 //! ConjugateBranch1, and ConjugateBranch2:
44 //! @code
45 //! ^YAxis
46 //! |
47 //! FirstConjugateBranch
48 //! |
49 //! Other            |                Main
50 //! --------------------- C ------------------------------>XAxis
51 //! Branch           |                Branch
52 //! |
53 //! |
54 //! SecondConjugateBranch
55 //! |
56 //! @endcode
57 //! Warning
58 //! The major radius can be less than the minor radius.
59 //! See Also
60 //! gce_MakeHypr2d which provides functions for more
61 //! complex hyperbola constructions
62 //! Geom2d_Hyperbola which provides additional functions
63 //! for constructing hyperbolas and works, in particular, with
64 //! the parametric equations of hyperbolas
65 class gp_Hypr2d 
66 {
67 public:
68
69   DEFINE_STANDARD_ALLOC
70
71   //! Creates of an indefinite hyperbola.
72   gp_Hypr2d()
73   : majorRadius (RealLast()),
74     minorRadius (RealLast())
75   {}
76
77   //! Creates a hyperbola with radii theMajorRadius and
78   //! theMinorRadius, centered on the origin of theMajorAxis
79   //! and where the unit vector of theMajorAxis is the "X
80   //! Direction" of the local coordinate system of the
81   //! hyperbola. This coordinate system is direct if theIsSense
82   //! is true (the default value), and indirect if theIsSense is false.
83   //! Warnings :
84   //! It is yet  possible to create an Hyperbola with
85   //! theMajorRadius <= theMinorRadius.
86   //! Raises ConstructionError if theMajorRadius < 0.0 or theMinorRadius < 0.0
87   gp_Hypr2d (const gp_Ax2d& theMajorAxis, const Standard_Real theMajorRadius,
88             const Standard_Real theMinorRadius, const Standard_Boolean theIsSense = Standard_True)
89   : majorRadius (theMajorRadius),
90     minorRadius (theMinorRadius)
91   {
92     pos = gp_Ax22d (theMajorAxis, theIsSense);
93     Standard_ConstructionError_Raise_if (theMinorRadius < 0.0 || theMajorRadius < 0.0,
94       "gp_Hypr2d() - invalid construction parameters");
95   }
96
97   //! a hyperbola with radii theMajorRadius and
98   //! theMinorRadius, positioned in the plane by coordinate system theA where:
99   //! -   the origin of theA is the center of the hyperbola,
100   //! -   the "X Direction" of theA defines the major axis of
101   //! the hyperbola, that is, the major radius
102   //! theMajorRadius is measured along this axis, and
103   //! -   the "Y Direction" of theA defines the minor axis of
104   //! the hyperbola, that is, the minor radius
105   //! theMinorRadius is measured along this axis, and
106   //! -   the orientation (direct or indirect sense) of theA
107   //! gives the implicit orientation of the hyperbola.
108   //! Warnings :
109   //! It is yet  possible to create an Hyperbola with
110   //! theMajorRadius <= theMinorRadius.
111   //! Raises ConstructionError if theMajorRadius < 0.0 or theMinorRadius < 0.0
112   gp_Hypr2d (const gp_Ax22d& theA, const Standard_Real theMajorRadius, const Standard_Real theMinorRadius)
113   : pos (theA),
114     majorRadius (theMajorRadius),
115     minorRadius (theMinorRadius)
116   {
117     Standard_ConstructionError_Raise_if (theMinorRadius < 0.0 || theMajorRadius < 0.0,
118                                          "gp_Hypr2d() - invalid construction parameters");
119   }
120
121   //! Modifies this hyperbola, by redefining its local
122   //! coordinate system so that its origin becomes theP.
123   void SetLocation (const gp_Pnt2d& theP) { pos.SetLocation (theP); }
124
125   //! Modifies the major or minor radius of this hyperbola.
126   //! Exceptions
127   //! Standard_ConstructionError if theMajorRadius or
128   //! MinorRadius is negative.
129   void SetMajorRadius (const Standard_Real theMajorRadius)
130   {
131     Standard_ConstructionError_Raise_if (theMajorRadius < 0.0,
132                                          "gp_Hypr2d::SetMajorRadius() - major radius should be greater or equal zero");
133     majorRadius = theMajorRadius;
134   }
135
136   //! Modifies the major or minor radius of this hyperbola.
137   //! Exceptions
138   //! Standard_ConstructionError if MajorRadius or
139   //! theMinorRadius is negative.
140   void SetMinorRadius (const Standard_Real theMinorRadius)
141   {
142     Standard_ConstructionError_Raise_if (theMinorRadius < 0.0,
143                                          "gp_Hypr2d::SetMinorRadius() - minor radius should be greater or equal zero");
144     minorRadius = theMinorRadius;
145   }
146
147   //! Modifies this hyperbola, by redefining its local
148   //! coordinate system so that it becomes theA.
149   void SetAxis (const gp_Ax22d& theA) { pos.SetAxis (theA); }
150
151   //! Changes the major axis of the hyperbola. The minor axis is
152   //! recomputed and the location of the hyperbola too.
153   void SetXAxis (const gp_Ax2d& theA) { pos.SetXAxis (theA); }
154
155   //! Changes the minor axis of the hyperbola.The minor axis is
156   //! recomputed and the location of the hyperbola too.
157   void SetYAxis (const gp_Ax2d& theA) { pos.SetYAxis (theA); }
158
159   //! In the local coordinate system of the hyperbola the equation of
160   //! the hyperbola is (X*X)/(A*A) - (Y*Y)/(B*B) = 1.0 and the
161   //! equation of the first asymptote is Y = (B/A)*X
162   //! where A is the major radius of the hyperbola and B the minor
163   //! radius of the hyperbola.
164   //! Raises ConstructionError if MajorRadius = 0.0
165   gp_Ax2d Asymptote1() const;
166
167   //! In the local coordinate system of the hyperbola the equation of
168   //! the hyperbola is (X*X)/(A*A) - (Y*Y)/(B*B) = 1.0 and the
169   //! equation of the first asymptote is Y = -(B/A)*X
170   //! where A is the major radius of the hyperbola and B the minor
171   //! radius of the hyperbola.
172   //! Raises ConstructionError if MajorRadius = 0.0
173   gp_Ax2d Asymptote2() const;
174
175   //! Computes the coefficients of the implicit equation of
176   //! the hyperbola :
177   //! theA * (X**2) + theB * (Y**2) + 2*theC*(X*Y) + 2*theD*X + 2*theE*Y + theF = 0.
178   Standard_EXPORT void Coefficients (Standard_Real& theA, Standard_Real& theB, Standard_Real& theC,
179                                      Standard_Real& theD, Standard_Real& theE, Standard_Real& theF) const;
180
181   //! Computes the branch of hyperbola which is on the positive side of the
182   //! "YAxis" of <me>.
183   gp_Hypr2d ConjugateBranch1() const
184   {
185     gp_Dir2d aV (pos.YDirection());
186     Standard_Boolean isSign = (pos.XDirection().Crossed (pos.YDirection())) >= 0.0;
187     return gp_Hypr2d (gp_Ax2d (pos.Location(), aV), minorRadius, majorRadius, isSign);
188   }
189
190   //! Computes the branch of hyperbola which is on the negative side of the
191   //! "YAxis" of <me>.
192   gp_Hypr2d ConjugateBranch2() const
193   {
194     gp_Dir2d aV (pos.YDirection().Reversed());
195     Standard_Boolean isSign = (pos.XDirection().Crossed (pos.YDirection())) >= 0.0;
196     return gp_Hypr2d (gp_Ax2d (pos.Location(), aV), minorRadius, majorRadius, isSign);
197   }
198
199   //! Computes the directrix which is the line normal to the XAxis of the hyperbola
200   //! in the local plane (Z = 0) at a distance d = MajorRadius / e
201   //! from the center of the hyperbola, where e is the eccentricity of
202   //! the hyperbola.
203   //! This line is parallel to the "YAxis". The intersection point
204   //! between the "Directrix1" and the "XAxis" is the "Location" point
205   //! of the "Directrix1".
206   //! This point is on the positive side of the "XAxis".
207   gp_Ax2d Directrix1() const;
208
209   //! This line is obtained by the symmetrical transformation
210   //! of "Directrix1" with respect to the "YAxis" of the hyperbola.
211   gp_Ax2d Directrix2() const;
212
213   //! Returns the eccentricity of the hyperbola (e > 1).
214   //! If f is the distance between the location of the hyperbola
215   //! and the Focus1 then the eccentricity e = f / MajorRadius. Raises DomainError if MajorRadius = 0.0.
216   Standard_Real Eccentricity() const
217   {
218     Standard_DomainError_Raise_if (majorRadius <= gp::Resolution(),
219                                    "gp_Hypr2d::Eccentricity() - major radius is zero");
220     return sqrt (majorRadius * majorRadius + minorRadius * minorRadius) / majorRadius;
221   }
222
223   //! Computes the focal distance. It is the distance between the
224   //! "Location" of the hyperbola and "Focus1" or "Focus2".
225   Standard_Real Focal() const
226   {
227     return 2.0 * sqrt (majorRadius * majorRadius + minorRadius * minorRadius);
228   }
229
230   //! Returns the first focus of the hyperbola. This focus is on the
231   //! positive side of the "XAxis" of the hyperbola.
232   gp_Pnt2d Focus1() const
233   {
234     Standard_Real aC = sqrt (majorRadius * majorRadius + minorRadius * minorRadius);
235     return gp_Pnt2d (pos.Location().X() + aC * pos.XDirection().X(), pos.Location().Y() + aC * pos.XDirection().Y());
236   }
237
238   //! Returns the second focus of the hyperbola. This focus is on the
239   //! negative side of the "XAxis" of the hyperbola.
240   gp_Pnt2d Focus2() const
241   {
242     Standard_Real aC = sqrt(majorRadius * majorRadius + minorRadius * minorRadius);
243     return gp_Pnt2d(pos.Location().X() - aC * pos.XDirection().X(), pos.Location().Y() - aC * pos.XDirection().Y());
244   }
245
246   //! Returns  the location point of the hyperbola.
247   //! It is the intersection point between the "XAxis" and
248   //! the "YAxis".
249   const gp_Pnt2d& Location() const { return pos.Location(); }
250
251   //! Returns the major radius of the hyperbola (it is the radius
252   //! corresponding to the "XAxis" of the hyperbola).
253   Standard_Real MajorRadius() const { return majorRadius; }
254
255   //! Returns the minor radius of the hyperbola (it is the radius
256   //! corresponding to the "YAxis" of the hyperbola).
257   Standard_Real MinorRadius() const { return minorRadius; }
258
259   //! Returns the branch of hyperbola obtained by doing the
260   //! symmetrical transformation of <me> with respect to the
261   //! "YAxis" of <me>.
262   gp_Hypr2d OtherBranch() const
263   {
264     Standard_Boolean isSign = (pos.XDirection().Crossed (pos.YDirection())) >= 0.0;
265     return gp_Hypr2d (gp_Ax2d (pos.Location(), pos.XDirection().Reversed()), majorRadius, minorRadius, isSign);
266   }
267
268   //! Returns p = (e * e - 1) * MajorRadius where e is the
269   //! eccentricity of the hyperbola.
270   //! Raises DomainError if MajorRadius = 0.0
271   Standard_Real Parameter() const
272   {
273     Standard_DomainError_Raise_if (majorRadius <= gp::Resolution(),
274                                    "gp_Hypr2d::Parameter() - major radius is zero");
275     return (minorRadius * minorRadius) / majorRadius;
276   }
277
278   //! Returns the axisplacement of the hyperbola.
279   const gp_Ax22d& Axis() const { return pos; }
280
281   //! Computes an axis whose
282   //! -   the origin is the center of this hyperbola, and
283   //! -   the unit vector is the "X Direction" or "Y Direction"
284   //! respectively of the local coordinate system of this hyperbola
285   //! Returns the major axis of the hyperbola.
286   gp_Ax2d XAxis() const { return pos.XAxis(); }
287
288   //! Computes an axis whose
289   //! -   the origin is the center of this hyperbola, and
290   //! -   the unit vector is the "X Direction" or "Y Direction"
291   //! respectively of the local coordinate system of this hyperbola
292   //! Returns the minor axis of the hyperbola.
293   gp_Ax2d YAxis() const { return pos.YAxis(); }
294
295   void Reverse()
296   {
297     gp_Dir2d aTemp = pos.YDirection();
298     aTemp.Reverse();
299     pos.SetAxis (gp_Ax22d(pos.Location(), pos.XDirection(), aTemp));
300   }
301
302   //! Reverses the orientation of the local coordinate system
303   //! of this hyperbola (the "Y Axis" is reversed). Therefore,
304   //! the implicit orientation of this hyperbola is reversed.
305   //! Note:
306   //! -   Reverse assigns the result to this hyperbola, while
307   //! -   Reversed creates a new one.
308   Standard_NODISCARD gp_Hypr2d Reversed() const;
309
310   //! Returns true if the local coordinate system is direct
311   //! and false in the other case.
312   Standard_Boolean IsDirect() const
313   {
314     return (pos.XDirection().Crossed (pos.YDirection())) >= 0.0;
315   }
316
317   Standard_EXPORT void Mirror (const gp_Pnt2d& theP);
318
319   //! Performs the symmetrical transformation of an hyperbola with
320   //! respect  to the point theP which is the center of the symmetry.
321   Standard_NODISCARD Standard_EXPORT gp_Hypr2d Mirrored (const gp_Pnt2d& theP) const;
322
323   Standard_EXPORT void Mirror (const gp_Ax2d& theA);
324
325   //! Performs the symmetrical transformation of an hyperbola with
326   //! respect to an axis placement which is the axis of the symmetry.
327   Standard_NODISCARD Standard_EXPORT gp_Hypr2d Mirrored (const gp_Ax2d& theA) const;
328
329   void Rotate (const gp_Pnt2d& theP, const Standard_Real theAng) { pos.Rotate (theP, theAng); }
330
331   //! Rotates an hyperbola. theP is the center of the rotation.
332   //! theAng is the angular value of the rotation in radians.
333   Standard_NODISCARD gp_Hypr2d Rotated (const gp_Pnt2d& theP, const Standard_Real theAng) const
334   {
335     gp_Hypr2d aH = *this;
336     aH.pos.Rotate (theP, theAng);
337     return aH;
338   }
339
340   void Scale (const gp_Pnt2d& theP, const Standard_Real theS);
341
342   //! Scales an hyperbola. <theS> is the scaling value.
343   //! If <theS> is positive only the location point is
344   //! modified. But if <theS> is negative the "XAxis" is
345   //! reversed and the "YAxis" too.
346   Standard_NODISCARD gp_Hypr2d Scaled (const gp_Pnt2d& theP, const Standard_Real theS) const;
347
348   void Transform (const gp_Trsf2d& theT);
349
350   //! Transforms an hyperbola with the transformation theT from
351   //! class Trsf2d.
352   Standard_NODISCARD gp_Hypr2d Transformed (const gp_Trsf2d& theT) const;
353
354   void Translate (const gp_Vec2d& theV) { pos.Translate (theV); }
355
356   //! Translates an hyperbola in the direction of the vector theV.
357   //! The magnitude of the translation is the vector's magnitude.
358   Standard_NODISCARD gp_Hypr2d Translated (const gp_Vec2d& theV) const
359   {
360     gp_Hypr2d aH = *this;
361     aH.pos.Translate (theV);
362     return aH;
363   }
364
365   void Translate(const gp_Pnt2d& theP1, const gp_Pnt2d& theP2) { pos.Translate (theP1, theP2); }
366
367   //! Translates an hyperbola from the point theP1 to the point theP2.
368   Standard_NODISCARD gp_Hypr2d Translated (const gp_Pnt2d& theP1, const gp_Pnt2d& theP2) const
369   {
370     gp_Hypr2d aH = *this;
371     aH.pos.Translate (theP1, theP2);
372     return aH;
373   }
374
375 private:
376
377   gp_Ax22d pos;
378   Standard_Real majorRadius;
379   Standard_Real minorRadius;
380
381 };
382
383 //=======================================================================
384 //function : Asymptote1
385 // purpose :
386 //=======================================================================
387 inline gp_Ax2d gp_Hypr2d::Asymptote1() const 
388 {
389   Standard_ConstructionError_Raise_if (majorRadius <= gp::Resolution(),
390                                        "gp_Hypr2d::Asymptote1() - major radius is zero");
391   gp_Dir2d aVdir = pos.XDirection();
392   gp_XY aCoord1 (pos.YDirection().XY());
393   gp_XY aCoord2 = aCoord1.Multiplied (minorRadius / majorRadius);
394   aCoord1.Add (aCoord2);
395   aVdir.SetXY (aCoord1);
396   return gp_Ax2d (pos.Location(), aVdir);
397 }
398
399 //=======================================================================
400 //function : Asymptote2
401 // purpose :
402 //=======================================================================
403 inline gp_Ax2d gp_Hypr2d::Asymptote2() const
404 {
405   Standard_ConstructionError_Raise_if (majorRadius <= gp::Resolution(),
406                                        "gp_Hypr2d::Asymptote2() - major radius is zero");
407   gp_Vec2d aVdir = pos.XDirection();
408   gp_XY  aCoord1 (pos.YDirection().XY());
409   gp_XY  aCoord2 = aCoord1.Multiplied (-minorRadius / majorRadius);
410   aCoord1.Add (aCoord2);
411   aVdir.SetXY (aCoord1);
412   return gp_Ax2d (pos.Location(), aVdir);
413 }
414
415 //=======================================================================
416 //function : Directrix1
417 // purpose :
418 //=======================================================================
419 inline gp_Ax2d gp_Hypr2d::Directrix1() const 
420 {
421   Standard_Real anE = Eccentricity();
422   gp_XY anOrig = pos.XDirection().XY();
423   anOrig.Multiply (majorRadius / anE);
424   anOrig.Add (pos.Location().XY());
425   return gp_Ax2d (gp_Pnt2d (anOrig), gp_Dir2d (pos.YDirection()));
426 }
427
428 //=======================================================================
429 //function : Directrix2
430 // purpose :
431 //=======================================================================
432 inline gp_Ax2d gp_Hypr2d::Directrix2() const
433 {
434   Standard_Real anE = Eccentricity();
435   gp_XY anOrig = pos.XDirection().XY();
436   anOrig.Multiply (Parameter() / anE);
437   anOrig.Add (Focus1().XY());
438   return gp_Ax2d (gp_Pnt2d (anOrig), gp_Dir2d (pos.YDirection()));
439 }
440
441 //=======================================================================
442 //function : Reversed
443 // purpose :
444 //=======================================================================
445 inline gp_Hypr2d gp_Hypr2d::Reversed() const
446 {
447   gp_Hypr2d aH = *this;
448   gp_Dir2d aTemp = pos.YDirection();
449   aTemp.Reverse ();
450   aH.pos.SetAxis (gp_Ax22d (pos.Location(),pos.XDirection(), aTemp));
451   return aH;
452 }
453
454 //=======================================================================
455 //function : Scale
456 // purpose :
457 //=======================================================================
458 inline void gp_Hypr2d::Scale (const gp_Pnt2d& theP, const Standard_Real theS)
459
460   majorRadius *= theS;
461   if (majorRadius < 0)
462   {
463     majorRadius = -majorRadius;
464   }
465   minorRadius *= theS;
466   if (minorRadius < 0)
467   {
468     minorRadius = -minorRadius;
469   }
470   pos.Scale (theP, theS);
471 }
472
473 //=======================================================================
474 //function : Scaled
475 // purpose :
476 //=======================================================================
477 inline gp_Hypr2d gp_Hypr2d::Scaled (const gp_Pnt2d& theP, const Standard_Real theS) const
478 {
479   gp_Hypr2d aH = *this;
480   aH.majorRadius *= theS;
481   if (aH.majorRadius < 0)
482   {
483     aH.majorRadius = -aH.majorRadius;
484   }
485   aH.minorRadius *= theS;
486   if (aH.minorRadius < 0)
487   {
488     aH.minorRadius = -aH.minorRadius;
489   }
490   aH.pos.Scale (theP, theS);
491   return aH; 
492 }
493
494 //=======================================================================
495 //function : Transform
496 // purpose :
497 //=======================================================================
498 inline void gp_Hypr2d::Transform (const gp_Trsf2d& theT)
499 {
500   majorRadius *= theT.ScaleFactor();
501   if (majorRadius < 0)
502   {
503     majorRadius = -majorRadius;
504   }
505   minorRadius *= theT.ScaleFactor();
506   if (minorRadius < 0)
507   {
508     minorRadius = -minorRadius;
509   }
510   pos.Transform (theT);
511 }
512
513 //=======================================================================
514 //function : Transformed
515 // purpose :
516 //=======================================================================
517 inline gp_Hypr2d gp_Hypr2d::Transformed (const gp_Trsf2d& theT) const
518 {
519   gp_Hypr2d aH = *this;
520   aH.majorRadius *= theT.ScaleFactor();
521   if (aH.majorRadius < 0)
522   {
523     aH.majorRadius = -aH.majorRadius;
524   }
525   aH.minorRadius *= theT.ScaleFactor();
526   if (aH.minorRadius < 0)
527   {
528     aH.minorRadius = -aH.minorRadius;
529   }
530   aH.pos.Transform (theT);
531   return aH;
532 }
533
534 #endif // _gp_Hypr2d_HeaderFile