1 // Copyright (C) 2017-2019 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File: GeomAPI_Ellipse2d.cpp
21 // Created: 26 April 2017
22 // Author: Artem ZHIDKOV
24 #include <GeomAPI_Ellipse2d.h>
25 #include <GeomAPI_Circ2d.h>
26 #include <GeomAPI_Dir2d.h>
27 #include <GeomAPI_Lin2d.h>
28 #include <GeomAPI_Pnt2d.h>
30 #include <Extrema_ExtCC2d.hxx>
31 #include <Extrema_ExtElC2d.hxx>
32 #include <Geom2d_Ellipse.hxx>
33 #include <Geom2dAdaptor_Curve.hxx>
34 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
35 #include <GeomLib_Tool.hxx>
36 #include <gp_Ax22d.hxx>
37 #include <gp_Elips2d.hxx>
38 #include <Precision.hxx>
40 #define MY_ELLIPSE implPtr<gp_Elips2d>()
42 static gp_Elips2d* newEllipse(const gp_Pnt2d& theCenter,
43 const gp_Dir2d& theXAxis,
44 const double theMajorRadius,
45 const double theMinorRadius)
47 if (theMajorRadius < theMinorRadius - Precision::Confusion()) {
48 return newEllipse(theCenter, gp_Dir2d(-theXAxis.Y(), theXAxis.X()),
49 theMinorRadius, theMajorRadius);
52 gp_Ax22d anAxis(theCenter, theXAxis);
53 return new gp_Elips2d(anAxis, theMajorRadius, theMinorRadius);
56 static gp_Elips2d* newEllipse(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
57 const std::shared_ptr<GeomAPI_Pnt2d>& theAxisPoint,
58 const std::shared_ptr<GeomAPI_Pnt2d>& thePassingPoint)
60 const gp_Pnt2d& aCenter = theCenter->impl<gp_Pnt2d>();
61 const gp_Pnt2d& anAxisPnt = theAxisPoint->impl<gp_Pnt2d>();
62 const gp_Pnt2d& aPassedPnt = thePassingPoint->impl<gp_Pnt2d>();
64 gp_Dir2d aXAxis(anAxisPnt.XY() - aCenter.XY());
65 double aMajorRadius = anAxisPnt.Distance(aCenter);
67 gp_XY aPassedDir = aPassedPnt.XY() - aCenter.XY();
69 double X = aPassedDir.Dot(aXAxis.XY()) / aMajorRadius;
70 if (Abs(X) > 1.0 - Precision::Confusion())
71 return 0; // ellipse cannot be created for such parameters
73 double Y = aPassedDir.CrossMagnitude(aXAxis.XY());
74 double aMinorRadius = Y / Sqrt(1. - X * X);
76 return newEllipse(aCenter, aXAxis, aMajorRadius, aMinorRadius);
80 GeomAPI_Ellipse2d::GeomAPI_Ellipse2d(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
81 const std::shared_ptr<GeomAPI_Dir2d>& theXAxis,
82 const double theMajorRadius,
83 const double theMinorRadius)
84 : GeomAPI_Interface(newEllipse(theCenter->impl<gp_Pnt2d>(), theXAxis->impl<gp_Dir2d>(),
85 theMajorRadius, theMinorRadius))
89 GeomAPI_Ellipse2d::GeomAPI_Ellipse2d(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
90 const std::shared_ptr<GeomAPI_Pnt2d>& theAxisPoint,
91 const std::shared_ptr<GeomAPI_Pnt2d>& thePassingPoint)
92 : GeomAPI_Interface(newEllipse(theCenter, theAxisPoint, thePassingPoint))
96 std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Ellipse2d::center() const
98 const gp_Pnt2d& aCenter = MY_ELLIPSE->Location();
99 return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aCenter.X(), aCenter.Y()));
102 std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Ellipse2d::firstFocus() const
104 const gp_Pnt2d& aFirst = MY_ELLIPSE->Focus1();
105 return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aFirst.X(), aFirst.Y()));
108 std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Ellipse2d::secondFocus() const
110 const gp_Pnt2d& aSecond = MY_ELLIPSE->Focus2();
111 return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aSecond.X(), aSecond.Y()));
114 double GeomAPI_Ellipse2d::minorRadius() const
116 return MY_ELLIPSE->MinorRadius();
119 double GeomAPI_Ellipse2d::majorRadius() const
121 return MY_ELLIPSE->MajorRadius();
124 template <typename EXTREMAPTR>
125 static double extrema(EXTREMAPTR theAlgo,
126 GeomPnt2dPtr& thePoint1,
127 GeomPnt2dPtr& thePoint2)
129 double aDistance = Precision::Infinite();
130 if (theAlgo->IsDone() && theAlgo->NbExt() > 0) {
131 Extrema_POnCurv2d aP1, aP2;
132 for (int i = 1; i <= theAlgo->NbExt(); ++i)
133 if (theAlgo->SquareDistance(i) < aDistance) {
134 aDistance = Sqrt(theAlgo->SquareDistance(i));
135 theAlgo->Points(i, aP1, aP2);
138 aDistance = Sqrt(aDistance);
139 thePoint1 = GeomPnt2dPtr(new GeomAPI_Pnt2d(aP1.Value().X(), aP1.Value().Y()));
140 thePoint2 = GeomPnt2dPtr(new GeomAPI_Pnt2d(aP2.Value().X(), aP2.Value().Y()));
145 double GeomAPI_Ellipse2d::distance(const std::shared_ptr<GeomAPI_Lin2d>& theLine,
146 std::shared_ptr<GeomAPI_Pnt2d>& thePointOnMe,
147 std::shared_ptr<GeomAPI_Pnt2d>& thePointOnLine)
149 Extrema_ExtElC2d anExtema(theLine->impl<gp_Lin2d>(), *MY_ELLIPSE);
150 return extrema(&anExtema, thePointOnLine, thePointOnMe);
153 double GeomAPI_Ellipse2d::distance(const std::shared_ptr<GeomAPI_Circ2d>& theCircle,
154 std::shared_ptr<GeomAPI_Pnt2d>& thePointOnMe,
155 std::shared_ptr<GeomAPI_Pnt2d>& thePointOnCircle)
157 Extrema_ExtElC2d anExtema(theCircle->impl<gp_Circ2d>(), *MY_ELLIPSE);
158 return extrema(&anExtema, thePointOnCircle, thePointOnMe);
161 double GeomAPI_Ellipse2d::distance(const std::shared_ptr<GeomAPI_Ellipse2d>& theEllipse,
162 std::shared_ptr<GeomAPI_Pnt2d>& thePointOnMe,
163 std::shared_ptr<GeomAPI_Pnt2d>& thePointOnEllipse)
165 Handle(Geom2d_Ellipse) anEllipse1 = new Geom2d_Ellipse(theEllipse->impl<gp_Elips2d>());
166 Handle(Geom2d_Ellipse) anEllipse2 = new Geom2d_Ellipse(*MY_ELLIPSE);
168 Extrema_ExtCC2d* anExtema =
169 new Extrema_ExtCC2d(Geom2dAdaptor_Curve(anEllipse1), Geom2dAdaptor_Curve(anEllipse2));
170 double aDistance = extrema(anExtema, thePointOnEllipse, thePointOnMe);
175 const std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Ellipse2d::project(
176 const std::shared_ptr<GeomAPI_Pnt2d>& thePoint) const
178 std::shared_ptr<GeomAPI_Pnt2d> aResult;
182 Handle(Geom2d_Ellipse) aEllipse = new Geom2d_Ellipse(*MY_ELLIPSE);
184 const gp_Pnt2d& aPoint = thePoint->impl<gp_Pnt2d>();
186 Geom2dAPI_ProjectPointOnCurve aProj(aPoint, aEllipse);
187 Standard_Integer aNbPoint = aProj.NbPoints();
189 gp_Pnt2d aNearest = aProj.NearestPoint();
190 aResult.reset(new GeomAPI_Pnt2d(aNearest.X(), aNearest.Y()));
195 const bool GeomAPI_Ellipse2d::parameter(const std::shared_ptr<GeomAPI_Pnt2d> thePoint,
196 const double theTolerance,
197 double& theParameter) const
199 Handle(Geom2d_Ellipse) aCurve = new Geom2d_Ellipse(*MY_ELLIPSE);
200 return GeomLib_Tool::Parameter(aCurve, thePoint->impl<gp_Pnt2d>(),
201 theTolerance, theParameter) == Standard_True;