Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-02 09:12:24

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_Elips2d_HeaderFile
0016 #define _gp_Elips2d_HeaderFile
0017 
0018 #include <gp.hxx>
0019 #include <gp_Ax22d.hxx>
0020 #include <gp_Ax2d.hxx>
0021 #include <gp_Pnt2d.hxx>
0022 #include <Standard_ConstructionError.hxx>
0023 
0024 //! Describes an ellipse in the plane (2D space).
0025 //! An ellipse is defined by its major and minor radii and
0026 //! positioned in the plane with a coordinate system (a
0027 //! gp_Ax22d object) as follows:
0028 //! -   the origin of the coordinate system is the center of the ellipse,
0029 //! -   its "X Direction" defines the major axis of the ellipse, and
0030 //! -   its "Y Direction" defines the minor axis of the ellipse.
0031 //! This coordinate system is the "local coordinate system"
0032 //! of the ellipse. Its orientation (direct or indirect) gives an
0033 //! implicit orientation to the ellipse. In this coordinate
0034 //! system, the equation of the ellipse is:
0035 //! @code
0036 //! X*X / (MajorRadius**2) + Y*Y / (MinorRadius**2) = 1.0
0037 //! @endcode
0038 //! See Also
0039 //! gce_MakeElips2d which provides functions for more
0040 //! complex ellipse constructions
0041 //! Geom2d_Ellipse which provides additional functions for
0042 //! constructing ellipses and works, in particular, with the
0043 //! parametric equations of ellipses
0044 class gp_Elips2d
0045 {
0046 public:
0047   DEFINE_STANDARD_ALLOC
0048 
0049   //! Creates an indefinite ellipse.
0050   constexpr gp_Elips2d() noexcept
0051       : majorRadius(RealLast()),
0052         minorRadius(RealSmall())
0053   {
0054   }
0055 
0056   //! Creates an ellipse with the major axis, the major and the
0057   //! minor radius. The location of the theMajorAxis is the center
0058   //! of the ellipse.
0059   //! The sense of parametrization is given by theIsSense.
0060   //! Warnings:
0061   //! It is possible to create an ellipse with
0062   //! theMajorRadius = theMinorRadius.
0063   //! Raises ConstructionError if theMajorRadius < theMinorRadius or theMinorRadius < 0.0
0064   constexpr gp_Elips2d(const gp_Ax2d& theMajorAxis,
0065                        const double   theMajorRadius,
0066                        const double   theMinorRadius,
0067                        const bool     theIsSense = true)
0068       : pos(theMajorAxis, theIsSense),
0069         majorRadius(theMajorRadius),
0070         minorRadius(theMinorRadius)
0071   {
0072     Standard_ConstructionError_Raise_if(theMinorRadius < 0.0 || theMajorRadius < theMinorRadius,
0073                                         "gp_Elips2d() - invalid construction parameters");
0074   }
0075 
0076   //! Creates an ellipse with radii MajorRadius and
0077   //! MinorRadius, positioned in the plane by coordinate system theA where:
0078   //! -   the origin of theA is the center of the ellipse,
0079   //! -   the "X Direction" of theA defines the major axis of
0080   //! the ellipse, that is, the major radius MajorRadius
0081   //! is measured along this axis, and
0082   //! -   the "Y Direction" of theA defines the minor axis of
0083   //! the ellipse, that is, the minor radius theMinorRadius
0084   //! is measured along this axis, and
0085   //! -   the orientation (direct or indirect sense) of theA
0086   //! gives the orientation of the ellipse.
0087   //! Warnings :
0088   //! It is possible to create an ellipse with
0089   //! theMajorRadius = theMinorRadius.
0090   //! Raises ConstructionError if theMajorRadius < theMinorRadius or theMinorRadius < 0.0
0091   constexpr gp_Elips2d(const gp_Ax22d& theA,
0092                        const double    theMajorRadius,
0093                        const double    theMinorRadius)
0094       : pos(theA),
0095         majorRadius(theMajorRadius),
0096         minorRadius(theMinorRadius)
0097   {
0098     Standard_ConstructionError_Raise_if(theMinorRadius < 0.0 || theMajorRadius < theMinorRadius,
0099                                         "gp_Elips2d() - invalid construction parameters");
0100   }
0101 
0102   //! Modifies this ellipse, by redefining its local coordinate system so that
0103   //! -   its origin becomes theP.
0104   constexpr void SetLocation(const gp_Pnt2d& theP) noexcept { pos.SetLocation(theP); }
0105 
0106   //! Changes the value of the major radius.
0107   //! Raises ConstructionError if theMajorRadius < MinorRadius.
0108   void SetMajorRadius(const double theMajorRadius)
0109   {
0110     Standard_ConstructionError_Raise_if(
0111       theMajorRadius < minorRadius,
0112       "gp_Elips2d::SetMajorRadius() - major radius should be greater or equal to minor radius");
0113     majorRadius = theMajorRadius;
0114   }
0115 
0116   //! Changes the value of the minor radius.
0117   //! Raises ConstructionError if MajorRadius < theMinorRadius or MinorRadius < 0.0
0118   void SetMinorRadius(const double theMinorRadius)
0119   {
0120     Standard_ConstructionError_Raise_if(theMinorRadius < 0.0 || majorRadius < theMinorRadius,
0121                                         "gp_Elips2d::SetMinorRadius() - minor radius should be a "
0122                                         "positive number lesser or equal to major radius");
0123     minorRadius = theMinorRadius;
0124   }
0125 
0126   //! Modifies this ellipse, by redefining its local coordinate system so that
0127   //! it becomes theA.
0128   constexpr void SetAxis(const gp_Ax22d& theA) noexcept { pos.SetAxis(theA); }
0129 
0130   //! Modifies this ellipse, by redefining its local coordinate system so that
0131   //! its origin and its "X Direction" become those
0132   //! of the axis theA. The "Y Direction" is then
0133   //! recomputed. The orientation of the local coordinate
0134   //! system is not modified.
0135   constexpr void SetXAxis(const gp_Ax2d& theA) { pos.SetXAxis(theA); }
0136 
0137   //! Modifies this ellipse, by redefining its local coordinate system so that
0138   //! its origin and its "Y Direction" become those
0139   //! of the axis theA. The "X Direction" is then
0140   //! recomputed. The orientation of the local coordinate
0141   //! system is not modified.
0142   constexpr void SetYAxis(const gp_Ax2d& theA) { pos.SetYAxis(theA); }
0143 
0144   //! Computes the area of the ellipse.
0145   constexpr double Area() const noexcept { return M_PI * majorRadius * minorRadius; }
0146 
0147   //! Returns the coefficients of the implicit equation of the ellipse.
0148   //! theA * (X**2) + theB * (Y**2) + 2*theC*(X*Y) + 2*theD*X + 2*theE*Y + theF = 0.
0149   Standard_EXPORT void Coefficients(double& theA,
0150                                     double& theB,
0151                                     double& theC,
0152                                     double& theD,
0153                                     double& theE,
0154                                     double& theF) const;
0155 
0156   //! This directrix is the line normal to the XAxis of the ellipse
0157   //! in the local plane (Z = 0) at a distance d = MajorRadius / e
0158   //! from the center of the ellipse, where e is the eccentricity of
0159   //! the ellipse.
0160   //! This line is parallel to the "YAxis". The intersection point
0161   //! between directrix1 and the "XAxis" is the location point of the
0162   //! directrix1. This point is on the positive side of the "XAxis".
0163   //!
0164   //! Raised if Eccentricity = 0.0. (The ellipse degenerates into a
0165   //! circle)
0166   gp_Ax2d Directrix1() const;
0167 
0168   //! This line is obtained by the symmetrical transformation
0169   //! of "Directrix1" with respect to the minor axis of the ellipse.
0170   //!
0171   //! Raised if Eccentricity = 0.0. (The ellipse degenerates into a
0172   //! circle).
0173   gp_Ax2d Directrix2() const;
0174 
0175   //! Returns the eccentricity of the ellipse between 0.0 and 1.0
0176   //! If f is the distance between the center of the ellipse and
0177   //! the Focus1 then the eccentricity e = f / MajorRadius.
0178   //! Returns 0 if MajorRadius = 0.
0179   double Eccentricity() const;
0180 
0181   //! Returns the distance between the center of the ellipse
0182   //! and focus1 or focus2.
0183   double Focal() const { return 2.0 * sqrt(majorRadius * majorRadius - minorRadius * minorRadius); }
0184 
0185   //! Returns the first focus of the ellipse. This focus is on the
0186   //! positive side of the major axis of the ellipse.
0187   gp_Pnt2d Focus1() const;
0188 
0189   //! Returns the second focus of the ellipse. This focus is on the
0190   //! negative side of the major axis of the ellipse.
0191   gp_Pnt2d Focus2() const;
0192 
0193   //! Returns the center of the ellipse.
0194   constexpr const gp_Pnt2d& Location() const noexcept { return pos.Location(); }
0195 
0196   //! Returns the major radius of the Ellipse.
0197   constexpr double MajorRadius() const noexcept { return majorRadius; }
0198 
0199   //! Returns the minor radius of the Ellipse.
0200   constexpr double MinorRadius() const noexcept { return minorRadius; }
0201 
0202   //! Returns p = (1 - e * e) * MajorRadius where e is the eccentricity
0203   //! of the ellipse.
0204   //! Returns 0 if MajorRadius = 0
0205   constexpr double Parameter() const noexcept;
0206 
0207   //! Returns the major axis of the ellipse.
0208   constexpr const gp_Ax22d& Axis() const noexcept { return pos; }
0209 
0210   //! Returns the major axis of the ellipse.
0211   gp_Ax2d XAxis() const noexcept { return pos.XAxis(); }
0212 
0213   //! Returns the minor axis of the ellipse.
0214   //! Reverses the direction of the circle.
0215   gp_Ax2d YAxis() const noexcept { return pos.YAxis(); }
0216 
0217   void Reverse() noexcept
0218   {
0219     gp_Dir2d aTemp = pos.YDirection();
0220     aTemp.Reverse();
0221     pos.SetAxis(gp_Ax22d(pos.Location(), pos.XDirection(), aTemp));
0222   }
0223 
0224   [[nodiscard]] gp_Elips2d Reversed() const noexcept;
0225 
0226   //! Returns true if the local coordinate system is direct
0227   //! and false in the other case.
0228   constexpr bool IsDirect() const noexcept
0229   {
0230     return (pos.XDirection().Crossed(pos.YDirection())) >= 0.0;
0231   }
0232 
0233   Standard_EXPORT void Mirror(const gp_Pnt2d& theP) noexcept;
0234 
0235   //! Performs the symmetrical transformation of a ellipse with respect
0236   //! to the point theP which is the center of the symmetry
0237   [[nodiscard]] Standard_EXPORT gp_Elips2d Mirrored(const gp_Pnt2d& theP) const noexcept;
0238 
0239   Standard_EXPORT void Mirror(const gp_Ax2d& theA) noexcept;
0240 
0241   //! Performs the symmetrical transformation of a ellipse with respect
0242   //! to an axis placement which is the axis of the symmetry.
0243   [[nodiscard]] Standard_EXPORT gp_Elips2d Mirrored(const gp_Ax2d& theA) const noexcept;
0244 
0245   void Rotate(const gp_Pnt2d& theP, const double theAng) { pos.Rotate(theP, theAng); }
0246 
0247   [[nodiscard]] gp_Elips2d Rotated(const gp_Pnt2d& theP, const double theAng) const
0248   {
0249     gp_Elips2d anE = *this;
0250     anE.pos.Rotate(theP, theAng);
0251     return anE;
0252   }
0253 
0254   void Scale(const gp_Pnt2d& theP, const double theS);
0255 
0256   //! Scales a ellipse. theS is the scaling value.
0257   [[nodiscard]] gp_Elips2d Scaled(const gp_Pnt2d& theP, const double theS) const;
0258 
0259   void Transform(const gp_Trsf2d& theT);
0260 
0261   //! Transforms an ellipse with the transformation theT from class Trsf2d.
0262   [[nodiscard]] gp_Elips2d Transformed(const gp_Trsf2d& theT) const;
0263 
0264   constexpr void Translate(const gp_Vec2d& theV) noexcept { pos.Translate(theV); }
0265 
0266   //! Translates a ellipse in the direction of the vector theV.
0267   //! The magnitude of the translation is the vector's magnitude.
0268   [[nodiscard]] constexpr gp_Elips2d Translated(const gp_Vec2d& theV) const noexcept
0269   {
0270     gp_Elips2d anE = *this;
0271     anE.pos.Translate(theV);
0272     return anE;
0273   }
0274 
0275   constexpr void Translate(const gp_Pnt2d& theP1, const gp_Pnt2d& theP2) noexcept
0276   {
0277     pos.Translate(theP1, theP2);
0278   }
0279 
0280   //! Translates a ellipse from the point theP1 to the point theP2.
0281   [[nodiscard]] constexpr gp_Elips2d Translated(const gp_Pnt2d& theP1,
0282                                                 const gp_Pnt2d& theP2) const noexcept
0283   {
0284     gp_Elips2d anE = *this;
0285     anE.pos.Translate(theP1, theP2);
0286     return anE;
0287   }
0288 
0289 private:
0290   gp_Ax22d pos;
0291   double   majorRadius;
0292   double   minorRadius;
0293 };
0294 
0295 //=================================================================================================
0296 
0297 inline gp_Ax2d gp_Elips2d::Directrix1() const
0298 {
0299   double anE = Eccentricity();
0300   Standard_ConstructionError_Raise_if(anE <= gp::Resolution(),
0301                                       "gp_Elips2d::Directrix1() - zero eccentricity");
0302   gp_XY anOrig = pos.XDirection().XY();
0303   anOrig.Multiply(majorRadius / anE);
0304   anOrig.Add(pos.Location().XY());
0305   return gp_Ax2d(gp_Pnt2d(anOrig), gp_Dir2d(pos.YDirection()));
0306 }
0307 
0308 //=================================================================================================
0309 
0310 inline gp_Ax2d gp_Elips2d::Directrix2() const
0311 {
0312   double anE = Eccentricity();
0313   Standard_ConstructionError_Raise_if(anE <= gp::Resolution(),
0314                                       "gp_Elips2d::Directrix2() - zero eccentricity");
0315   gp_XY anOrig = pos.XDirection().XY();
0316   anOrig.Multiply(-majorRadius / anE);
0317   anOrig.Add(pos.Location().XY());
0318   return gp_Ax2d(gp_Pnt2d(anOrig), gp_Dir2d(pos.YDirection()));
0319 }
0320 
0321 //=================================================================================================
0322 
0323 inline double gp_Elips2d::Eccentricity() const
0324 {
0325   if (majorRadius == 0.0)
0326   {
0327     return 0.0;
0328   }
0329   else
0330   {
0331     return sqrt(majorRadius * majorRadius - minorRadius * minorRadius) / majorRadius;
0332   }
0333 }
0334 
0335 //=================================================================================================
0336 
0337 inline gp_Pnt2d gp_Elips2d::Focus1() const
0338 {
0339   double          aC  = sqrt(majorRadius * majorRadius - minorRadius * minorRadius);
0340   const gp_Pnt2d& aPP = pos.Location();
0341   const gp_Dir2d& aDD = pos.XDirection();
0342   return gp_Pnt2d(aPP.X() + aC * aDD.X(), aPP.Y() + aC * aDD.Y());
0343 }
0344 
0345 //=================================================================================================
0346 
0347 inline gp_Pnt2d gp_Elips2d::Focus2() const
0348 {
0349   double          aC  = sqrt(majorRadius * majorRadius - minorRadius * minorRadius);
0350   const gp_Pnt2d& aPP = pos.Location();
0351   const gp_Dir2d& aDD = pos.XDirection();
0352   return gp_Pnt2d(aPP.X() - aC * aDD.X(), aPP.Y() - aC * aDD.Y());
0353 }
0354 
0355 //=================================================================================================
0356 
0357 inline void gp_Elips2d::Scale(const gp_Pnt2d& theP, const double theS)
0358 {
0359   majorRadius *= theS;
0360   if (majorRadius < 0)
0361   {
0362     majorRadius = -majorRadius;
0363   }
0364   minorRadius *= theS;
0365   if (minorRadius < 0)
0366   {
0367     minorRadius = -minorRadius;
0368   }
0369   pos.Scale(theP, theS);
0370 }
0371 
0372 //=================================================================================================
0373 
0374 inline gp_Elips2d gp_Elips2d::Scaled(const gp_Pnt2d& theP, const double theS) const
0375 {
0376   gp_Elips2d anE = *this;
0377   anE.majorRadius *= theS;
0378   if (anE.majorRadius < 0)
0379   {
0380     anE.majorRadius = -anE.majorRadius;
0381   }
0382   anE.minorRadius *= theS;
0383   if (anE.minorRadius < 0)
0384   {
0385     anE.minorRadius = -anE.minorRadius;
0386   }
0387   anE.pos.Scale(theP, theS);
0388   return anE;
0389 }
0390 
0391 //=================================================================================================
0392 
0393 inline constexpr double gp_Elips2d::Parameter() const noexcept
0394 {
0395   if (majorRadius == 0.0)
0396   {
0397     return 0.0;
0398   }
0399   else
0400   {
0401     return (minorRadius * minorRadius) / majorRadius;
0402   }
0403 }
0404 
0405 //=================================================================================================
0406 
0407 inline gp_Elips2d gp_Elips2d::Reversed() const noexcept
0408 {
0409   gp_Elips2d anE   = *this;
0410   gp_Dir2d   aTemp = pos.YDirection();
0411   aTemp.Reverse();
0412   anE.pos.SetAxis(gp_Ax22d(pos.Location(), pos.XDirection(), aTemp));
0413   return anE;
0414 }
0415 
0416 //=================================================================================================
0417 
0418 inline void gp_Elips2d::Transform(const gp_Trsf2d& theT)
0419 {
0420   double aTSca = theT.ScaleFactor();
0421   if (aTSca < 0.0)
0422   {
0423     aTSca = -aTSca;
0424   }
0425   majorRadius *= aTSca;
0426   minorRadius *= aTSca;
0427   pos.Transform(theT);
0428 }
0429 
0430 //=================================================================================================
0431 
0432 inline gp_Elips2d gp_Elips2d::Transformed(const gp_Trsf2d& theT) const
0433 {
0434   gp_Elips2d anE = *this;
0435   anE.majorRadius *= theT.ScaleFactor();
0436   if (anE.majorRadius < 0)
0437   {
0438     anE.majorRadius = -anE.majorRadius;
0439   }
0440   anE.minorRadius *= theT.ScaleFactor();
0441   if (anE.minorRadius < 0)
0442   {
0443     anE.minorRadius = -anE.minorRadius;
0444   }
0445   anE.pos.Transform(theT);
0446   return anE;
0447 }
0448 
0449 #endif // _gp_Elips2d_HeaderFile