Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-20 08:34:58

0001 // Copyright (c) 1991-1999 Matra Datavision
0002 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0003 //
0004 // This file is part of Open CASCADE Technology software library.
0005 //
0006 // This library is free software; you can redistribute it and/or modify it under
0007 // the terms of the GNU Lesser General Public License version 2.1 as published
0008 // by the Free Software Foundation, with special exception defined in the file
0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0010 // distribution for complete text of the license and disclaimer of any warranty.
0011 //
0012 // Alternatively, this file may be used under the terms of Open CASCADE
0013 // commercial license or contractual agreement.
0014 
0015 #ifndef _gp_Hypr_HeaderFile
0016 #define _gp_Hypr_HeaderFile
0017 
0018 #include <gp.hxx>
0019 #include <gp_Ax1.hxx>
0020 #include <gp_Ax2.hxx>
0021 #include <gp_Pnt.hxx>
0022 #include <Standard_DomainError.hxx>
0023 #include <Standard_ConstructionError.hxx>
0024 
0025 //! Describes a branch of a hyperbola in 3D space.
0026 //! A hyperbola is defined by its major and minor radii and
0027 //! positioned in space with a coordinate system (a gp_Ax2
0028 //! object) of which:
0029 //! -   the origin is the center of the hyperbola,
0030 //! -   the "X Direction" defines the major axis of the
0031 //! hyperbola, and
0032 //! - the "Y Direction" defines the minor axis of the hyperbola.
0033 //! The origin, "X Direction" and "Y Direction" of this
0034 //! coordinate system together define the plane of the
0035 //! hyperbola. This coordinate system is the "local
0036 //! coordinate system" of the hyperbola. In this coordinate
0037 //! system, the equation of the hyperbola is:
0038 //! X*X/(MajorRadius**2)-Y*Y/(MinorRadius**2) = 1.0
0039 //! The branch of the hyperbola described is the one located
0040 //! on the positive side of the major axis.
0041 //! The "main Direction" of the local coordinate system is a
0042 //! normal vector to the plane of the hyperbola. This vector
0043 //! gives an implicit orientation to the hyperbola. We refer to
0044 //! the "main Axis" of the local coordinate system as the
0045 //! "Axis" of the hyperbola.
0046 //! The following schema shows the plane of the hyperbola,
0047 //! and in it, the respective positions of the three branches of
0048 //! hyperbolas constructed with the functions OtherBranch,
0049 //! ConjugateBranch1, and ConjugateBranch2:
0050 //! @code
0051 //! ^YAxis
0052 //! |
0053 //! FirstConjugateBranch
0054 //! |
0055 //! Other            |                Main
0056 //! --------------------- C ------------------------------>XAxis
0057 //! Branch           |                Branch
0058 //! |
0059 //! |
0060 //! SecondConjugateBranch
0061 //! |                  ^YAxis
0062 //! @endcode
0063 //! Warning
0064 //! The major radius can be less than the minor radius.
0065 //! See Also
0066 //! gce_MakeHypr which provides functions for more
0067 //! complex hyperbola constructions
0068 //! Geom_Hyperbola which provides additional functions for
0069 //! constructing hyperbolas and works, in particular, with the
0070 //! parametric equations of hyperbolas
0071 class gp_Hypr
0072 {
0073 public:
0074   DEFINE_STANDARD_ALLOC
0075 
0076   //! Creates of an indefinite hyperbola.
0077   gp_Hypr()
0078       : majorRadius(RealLast()),
0079         minorRadius(RealFirst())
0080   {
0081   }
0082 
0083   //! Creates a hyperbola with radius theMajorRadius and
0084   //! theMinorRadius, positioned in the space by the
0085   //! coordinate system theA2 such that:
0086   //! -   the origin of theA2 is the center of the hyperbola,
0087   //! -   the "X Direction" of theA2 defines the major axis of
0088   //! the hyperbola, that is, the major radius
0089   //! theMajorRadius is measured along this axis, and
0090   //! -   the "Y Direction" of theA2 defines the minor axis of
0091   //! the hyperbola, that is, the minor radius
0092   //! theMinorRadius is measured along this axis.
0093   //! Note: This class does not prevent the creation of a
0094   //! hyperbola where:
0095   //! -   theMajorAxis is equal to theMinorAxis, or
0096   //! -   theMajorAxis is less than theMinorAxis.
0097   //! Exceptions
0098   //! Standard_ConstructionError if theMajorAxis or theMinorAxis is negative.
0099   //! Raises ConstructionError if theMajorRadius < 0.0 or theMinorRadius < 0.0
0100   //! Raised if theMajorRadius < 0.0 or theMinorRadius < 0.0
0101   gp_Hypr(const gp_Ax2&       theA2,
0102           const Standard_Real theMajorRadius,
0103           const Standard_Real theMinorRadius)
0104       : pos(theA2),
0105         majorRadius(theMajorRadius),
0106         minorRadius(theMinorRadius)
0107   {
0108     Standard_ConstructionError_Raise_if(theMinorRadius < 0.0 || theMajorRadius < 0.0,
0109                                         "gp_Hypr() - invalid construction parameters");
0110   }
0111 
0112   //! Modifies this hyperbola, by redefining its local coordinate
0113   //! system so that:
0114   //! -   its origin and "main Direction" become those of the
0115   //! axis theA1 (the "X Direction" and "Y Direction" are then
0116   //! recomputed in the same way as for any gp_Ax2).
0117   //! Raises ConstructionError if the direction of theA1 is parallel to the direction of
0118   //! the "XAxis" of the hyperbola.
0119   void SetAxis(const gp_Ax1& theA1) { pos.SetAxis(theA1); }
0120 
0121   //! Modifies this hyperbola, by redefining its local coordinate
0122   //! system so that its origin becomes theP.
0123   void SetLocation(const gp_Pnt& theP) { pos = gp_Ax2(theP, pos.Direction(), pos.XDirection()); }
0124 
0125   //! Modifies the major  radius of this hyperbola.
0126   //! Exceptions
0127   //! Standard_ConstructionError if theMajorRadius is negative.
0128   void SetMajorRadius(const Standard_Real theMajorRadius)
0129   {
0130     Standard_ConstructionError_Raise_if(
0131       theMajorRadius < 0.0,
0132       "gp_Hypr::SetMajorRadius() - major radius should be greater or equal zero");
0133     majorRadius = theMajorRadius;
0134   }
0135 
0136   //! Modifies the minor  radius of this hyperbola.
0137   //! Exceptions
0138   //! Standard_ConstructionError if theMinorRadius is negative.
0139   void SetMinorRadius(const Standard_Real theMinorRadius)
0140   {
0141     Standard_ConstructionError_Raise_if(
0142       theMinorRadius < 0.0,
0143       "gp_Hypr::SetMinorRadius() - minor radius should be greater or equal zero");
0144     minorRadius = theMinorRadius;
0145   }
0146 
0147   //! Modifies this hyperbola, by redefining its local coordinate
0148   //! system so that it becomes A2.
0149   void SetPosition(const gp_Ax2& theA2) { pos = theA2; }
0150 
0151   //! In the local coordinate system of the hyperbola the equation of
0152   //! the hyperbola is (X*X)/(A*A) - (Y*Y)/(B*B) = 1.0 and the
0153   //! equation of the first asymptote is Y = (B/A)*X
0154   //! where A is the major radius and B is the minor radius. Raises ConstructionError if MajorRadius
0155   //! = 0.0
0156   gp_Ax1 Asymptote1() const;
0157 
0158   //! In the local coordinate system of the hyperbola the equation of
0159   //! the hyperbola is (X*X)/(A*A) - (Y*Y)/(B*B) = 1.0 and the
0160   //! equation of the first asymptote is Y = -(B/A)*X.
0161   //! where A is the major radius and B is the minor radius. Raises ConstructionError if MajorRadius
0162   //! = 0.0
0163   gp_Ax1 Asymptote2() const;
0164 
0165   //! Returns the axis passing through the center,
0166   //! and normal to the plane of this hyperbola.
0167   const gp_Ax1& Axis() const { return pos.Axis(); }
0168 
0169   //! Computes the branch of hyperbola which is on the positive side of the
0170   //! "YAxis" of <me>.
0171   gp_Hypr ConjugateBranch1() const
0172   {
0173     return gp_Hypr(gp_Ax2(pos.Location(), pos.Direction(), pos.YDirection()),
0174                    minorRadius,
0175                    majorRadius);
0176   }
0177 
0178   //! Computes the branch of hyperbola which is on the negative side of the
0179   //! "YAxis" of <me>.
0180   gp_Hypr ConjugateBranch2() const
0181   {
0182     gp_Dir aD = pos.YDirection();
0183     aD.Reverse();
0184     return gp_Hypr(gp_Ax2(pos.Location(), pos.Direction(), aD), minorRadius, majorRadius);
0185   }
0186 
0187   //! This directrix is the line normal to the XAxis of the hyperbola
0188   //! in the local plane (Z = 0) at a distance d = MajorRadius / e
0189   //! from the center of the hyperbola, where e is the eccentricity of
0190   //! the hyperbola.
0191   //! This line is parallel to the "YAxis". The intersection point
0192   //! between the directrix1 and the "XAxis" is the "Location" point
0193   //! of the directrix1. This point is on the positive side of the
0194   //! "XAxis".
0195   gp_Ax1 Directrix1() const;
0196 
0197   //! This line is obtained by the symmetrical transformation
0198   //! of "Directrix1" with respect to the "YAxis" of the hyperbola.
0199   gp_Ax1 Directrix2() const;
0200 
0201   //! Returns the eccentricity of the hyperbola (e > 1).
0202   //! If f is the distance between the location of the hyperbola
0203   //! and the Focus1 then the eccentricity e = f / MajorRadius. Raises DomainError if MajorRadius =
0204   //! 0.0
0205   Standard_Real Eccentricity() const
0206   {
0207     Standard_DomainError_Raise_if(majorRadius <= gp::Resolution(),
0208                                   "gp_Hypr::Eccentricity() - major radius is zero");
0209     return sqrt(majorRadius * majorRadius + minorRadius * minorRadius) / majorRadius;
0210   }
0211 
0212   //! Computes the focal distance. It is the distance between the
0213   //! the two focus of the hyperbola.
0214   Standard_Real Focal() const
0215   {
0216     return 2.0 * sqrt(majorRadius * majorRadius + minorRadius * minorRadius);
0217   }
0218 
0219   //! Returns the first focus of the hyperbola. This focus is on the
0220   //! positive side of the "XAxis" of the hyperbola.
0221   gp_Pnt Focus1() const;
0222 
0223   //! Returns the second focus of the hyperbola. This focus is on the
0224   //! negative side of the "XAxis" of the hyperbola.
0225   gp_Pnt Focus2() const;
0226 
0227   //! Returns  the location point of the hyperbola. It is the
0228   //! intersection point between the "XAxis" and the "YAxis".
0229   const gp_Pnt& Location() const { return pos.Location(); }
0230 
0231   //! Returns the major radius of the hyperbola. It is the radius
0232   //! on the "XAxis" of the hyperbola.
0233   Standard_Real MajorRadius() const { return majorRadius; }
0234 
0235   //! Returns the minor radius of the hyperbola. It is the radius
0236   //! on the "YAxis" of the hyperbola.
0237   Standard_Real MinorRadius() const { return minorRadius; }
0238 
0239   //! Returns the branch of hyperbola obtained by doing the
0240   //! symmetrical transformation of <me> with respect to the
0241   //! "YAxis"  of <me>.
0242   gp_Hypr OtherBranch() const
0243   {
0244     gp_Dir aD = pos.XDirection();
0245     aD.Reverse();
0246     return gp_Hypr(gp_Ax2(pos.Location(), pos.Direction(), aD), majorRadius, minorRadius);
0247   }
0248 
0249   //! Returns p = (e * e - 1) * MajorRadius where e is the
0250   //! eccentricity of the hyperbola.
0251   //! Raises DomainError if MajorRadius = 0.0
0252   Standard_Real Parameter() const
0253   {
0254     Standard_DomainError_Raise_if(majorRadius <= gp::Resolution(),
0255                                   "gp_Hypr::Parameter() - major radius is zero");
0256     return (minorRadius * minorRadius) / majorRadius;
0257   }
0258 
0259   //! Returns the coordinate system of the hyperbola.
0260   const gp_Ax2& Position() const { return pos; }
0261 
0262   //! Computes an axis, whose
0263   //! -   the origin is the center of this hyperbola, and
0264   //! -   the unit vector is the "X Direction"
0265   //! of the local coordinate system of this hyperbola.
0266   //! These axes are, the major axis (the "X
0267   //! Axis") and  of this hyperboReturns the "XAxis" of the hyperbola.
0268   gp_Ax1 XAxis() const { return gp_Ax1(pos.Location(), pos.XDirection()); }
0269 
0270   //! Computes an axis, whose
0271   //! -   the origin is the center of this hyperbola, and
0272   //! -   the unit vector is the "Y Direction"
0273   //! of the local coordinate system of this hyperbola.
0274   //! These axes are the minor axis (the "Y Axis") of this hyperbola
0275   gp_Ax1 YAxis() const { return gp_Ax1(pos.Location(), pos.YDirection()); }
0276 
0277   Standard_EXPORT void Mirror(const gp_Pnt& theP);
0278 
0279   //! Performs the symmetrical transformation of an hyperbola with
0280   //! respect  to the point theP which is the center of the symmetry.
0281   Standard_NODISCARD Standard_EXPORT gp_Hypr Mirrored(const gp_Pnt& theP) const;
0282 
0283   Standard_EXPORT void Mirror(const gp_Ax1& theA1);
0284 
0285   //! Performs the symmetrical transformation of an hyperbola with
0286   //! respect to an axis placement which is the axis of the symmetry.
0287   Standard_NODISCARD Standard_EXPORT gp_Hypr Mirrored(const gp_Ax1& theA1) const;
0288 
0289   Standard_EXPORT void Mirror(const gp_Ax2& theA2);
0290 
0291   //! Performs the symmetrical transformation of an hyperbola with
0292   //! respect to a plane. The axis placement theA2 locates the plane
0293   //! of the symmetry (Location, XDirection, YDirection).
0294   Standard_NODISCARD Standard_EXPORT gp_Hypr Mirrored(const gp_Ax2& theA2) const;
0295 
0296   void Rotate(const gp_Ax1& theA1, const Standard_Real theAng) { pos.Rotate(theA1, theAng); }
0297 
0298   //! Rotates an hyperbola. theA1 is the axis of the rotation.
0299   //! theAng is the angular value of the rotation in radians.
0300   Standard_NODISCARD gp_Hypr Rotated(const gp_Ax1& theA1, const Standard_Real theAng) const
0301   {
0302     gp_Hypr aH = *this;
0303     aH.pos.Rotate(theA1, theAng);
0304     return aH;
0305   }
0306 
0307   void Scale(const gp_Pnt& theP, const Standard_Real theS);
0308 
0309   //! Scales an hyperbola. theS is the scaling value.
0310   Standard_NODISCARD gp_Hypr Scaled(const gp_Pnt& theP, const Standard_Real theS) const;
0311 
0312   void Transform(const gp_Trsf& theT);
0313 
0314   //! Transforms an hyperbola with the transformation theT from
0315   //! class Trsf.
0316   Standard_NODISCARD gp_Hypr Transformed(const gp_Trsf& theT) const;
0317 
0318   void Translate(const gp_Vec& theV) { pos.Translate(theV); }
0319 
0320   //! Translates an hyperbola in the direction of the vector theV.
0321   //! The magnitude of the translation is the vector's magnitude.
0322   Standard_NODISCARD gp_Hypr Translated(const gp_Vec& theV) const
0323   {
0324     gp_Hypr aH = *this;
0325     aH.pos.Translate(theV);
0326     return aH;
0327   }
0328 
0329   void Translate(const gp_Pnt& theP1, const gp_Pnt& theP2) { pos.Translate(theP1, theP2); }
0330 
0331   //! Translates an hyperbola from the point theP1 to the point theP2.
0332   Standard_NODISCARD gp_Hypr Translated(const gp_Pnt& theP1, const gp_Pnt& theP2) const
0333   {
0334     gp_Hypr aH = *this;
0335     aH.pos.Translate(theP1, theP2);
0336     return aH;
0337   }
0338 
0339 private:
0340   gp_Ax2        pos;
0341   Standard_Real majorRadius;
0342   Standard_Real minorRadius;
0343 };
0344 
0345 //=======================================================================
0346 // function : Asymptote1
0347 // purpose :
0348 //=======================================================================
0349 inline gp_Ax1 gp_Hypr::Asymptote1() const
0350 {
0351   Standard_ConstructionError_Raise_if(majorRadius <= gp::Resolution(),
0352                                       "gp_Hypr::Asymptote1() - major radius is zero");
0353   gp_Vec aV1 = gp_Vec(pos.YDirection());
0354   aV1.Multiply(minorRadius / majorRadius);
0355   gp_Vec aV = gp_Vec(pos.XDirection());
0356   aV.Add(aV1);
0357   return gp_Ax1(pos.Location(), gp_Dir(aV));
0358 }
0359 
0360 //=======================================================================
0361 // function : Asymptote2
0362 // purpose :
0363 //=======================================================================
0364 inline gp_Ax1 gp_Hypr::Asymptote2() const
0365 {
0366   Standard_ConstructionError_Raise_if(majorRadius <= gp::Resolution(),
0367                                       "gp_Hypr::Asymptote1() - major radius is zero");
0368   gp_Vec aV1 = gp_Vec(pos.YDirection());
0369   aV1.Multiply(-minorRadius / majorRadius);
0370   gp_Vec aV = gp_Vec(pos.XDirection());
0371   aV.Add(aV1);
0372   return gp_Ax1(pos.Location(), gp_Dir(aV));
0373 }
0374 
0375 //=======================================================================
0376 // function : Focus1
0377 // purpose :
0378 //=======================================================================
0379 inline gp_Pnt gp_Hypr::Focus1() const
0380 {
0381   Standard_Real aC  = sqrt(majorRadius * majorRadius + minorRadius * minorRadius);
0382   const gp_Pnt& aPP = pos.Location();
0383   const gp_Dir& aDD = pos.XDirection();
0384   return gp_Pnt(aPP.X() + aC * aDD.X(), aPP.Y() + aC * aDD.Y(), aPP.Z() + aC * aDD.Z());
0385 }
0386 
0387 //=======================================================================
0388 // function : Focus2
0389 // purpose :
0390 //=======================================================================
0391 inline gp_Pnt gp_Hypr::Focus2() const
0392 {
0393   Standard_Real aC  = sqrt(majorRadius * majorRadius + minorRadius * minorRadius);
0394   const gp_Pnt& aPP = pos.Location();
0395   const gp_Dir& aDD = pos.XDirection();
0396   return gp_Pnt(aPP.X() - aC * aDD.X(), aPP.Y() - aC * aDD.Y(), aPP.Z() - aC * aDD.Z());
0397 }
0398 
0399 //=======================================================================
0400 // function : Scale
0401 // purpose :
0402 //=======================================================================
0403 inline void gp_Hypr::Scale(const gp_Pnt& theP, const Standard_Real theS)
0404 {
0405   majorRadius *= theS;
0406   if (majorRadius < 0)
0407   {
0408     majorRadius = -majorRadius;
0409   }
0410   minorRadius *= theS;
0411   if (minorRadius < 0)
0412   {
0413     minorRadius = -minorRadius;
0414   }
0415   pos.Scale(theP, theS);
0416 }
0417 
0418 //=======================================================================
0419 // function : Scaled
0420 // purpose :
0421 //=======================================================================
0422 inline gp_Hypr gp_Hypr::Scaled(const gp_Pnt& theP, const Standard_Real theS) const
0423 {
0424   gp_Hypr aH = *this;
0425   aH.majorRadius *= theS;
0426   if (aH.majorRadius < 0)
0427   {
0428     aH.majorRadius = -aH.majorRadius;
0429   }
0430   aH.minorRadius *= theS;
0431   if (aH.minorRadius < 0)
0432   {
0433     aH.minorRadius = -aH.minorRadius;
0434   }
0435   aH.pos.Scale(theP, theS);
0436   return aH;
0437 }
0438 
0439 //=======================================================================
0440 // function : Transform
0441 // purpose :
0442 //=======================================================================
0443 inline void gp_Hypr::Transform(const gp_Trsf& theT)
0444 {
0445   majorRadius *= theT.ScaleFactor();
0446   if (majorRadius < 0)
0447   {
0448     majorRadius = -majorRadius;
0449   }
0450   minorRadius *= theT.ScaleFactor();
0451   if (minorRadius < 0)
0452   {
0453     minorRadius = -minorRadius;
0454   }
0455   pos.Transform(theT);
0456 }
0457 
0458 //=======================================================================
0459 // function : Transformed
0460 // purpose :
0461 //=======================================================================
0462 inline gp_Hypr gp_Hypr::Transformed(const gp_Trsf& theT) const
0463 {
0464   gp_Hypr aH = *this;
0465   aH.majorRadius *= theT.ScaleFactor();
0466   if (aH.majorRadius < 0)
0467   {
0468     aH.majorRadius = -aH.majorRadius;
0469   }
0470   aH.minorRadius *= theT.ScaleFactor();
0471   if (aH.minorRadius < 0)
0472   {
0473     aH.minorRadius = -aH.minorRadius;
0474   }
0475   aH.pos.Transform(theT);
0476   return aH;
0477 }
0478 
0479 //=======================================================================
0480 // function : Directrix1
0481 // purpose :
0482 //=======================================================================
0483 inline gp_Ax1 gp_Hypr::Directrix1() const
0484 {
0485   Standard_Real anE    = Eccentricity();
0486   gp_XYZ        anOrig = pos.XDirection().XYZ();
0487   anOrig.Multiply(majorRadius / anE);
0488   anOrig.Add(pos.Location().XYZ());
0489   return gp_Ax1(gp_Pnt(anOrig), pos.YDirection());
0490 }
0491 
0492 //=======================================================================
0493 // function : Directrix2
0494 // purpose :
0495 //=======================================================================
0496 inline gp_Ax1 gp_Hypr::Directrix2() const
0497 {
0498   Standard_Real anE    = Eccentricity();
0499   gp_XYZ        anOrig = pos.XDirection().XYZ();
0500   anOrig.Multiply(-majorRadius / anE);
0501   anOrig.Add(pos.Location().XYZ());
0502   return gp_Ax1(gp_Pnt(anOrig), pos.YDirection());
0503 }
0504 
0505 #endif // _gp_Hypr_HeaderFile