1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: GeomAPI_Circ2d.cpp
4 // Created: 29 May 2014
5 // Author: Artem ZHIDKOV
7 #include <GeomAPI_Circ2d.h>
8 #include <GeomAPI_Ax3.h>
9 #include <GeomAPI_Pnt2d.h>
10 #include <GeomAPI_Dir2d.h>
11 #include <GeomAPI_Shape.h>
13 #include <BRep_Tool.hxx>
15 #include <gp_Dir2d.hxx>
16 #include <gp_Circ2d.hxx>
17 #include <gp_Lin2d.hxx>
18 #include <gp_Pnt2d.hxx>
19 #include <gp_Ax2d.hxx>
20 #include <GccAna_Circ2d2TanRad.hxx>
21 #include <GccAna_Circ2d3Tan.hxx>
22 #include <GccAna_Circ2dTanCen.hxx>
24 #include <GccEnt_QualifiedCirc.hxx>
25 #include <GccEnt_QualifiedLin.hxx>
26 #include <GeomLib_Tool.hxx>
27 #include <Geom2d_Circle.hxx>
28 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
29 #include <Geom_Plane.hxx>
30 #include <IntAna2d_AnaIntersection.hxx>
31 #include <Precision.hxx>
33 #include <TopoDS_Edge.hxx>
37 #define MY_CIRC2D implPtr<gp_Circ2d>()
39 typedef std::shared_ptr<Geom2dAdaptor_Curve> CurveAdaptorPtr;
40 typedef std::vector< std::shared_ptr<GccEnt_QualifiedCirc> > VectorOfGccCirc;
41 typedef std::vector< std::shared_ptr<GccEnt_QualifiedLin> > VectorOfGccLine;
43 // Provide different mechanisms to create circle:
44 // * by passing points
46 // * with specified radius
51 CircleBuilder(const std::shared_ptr<GeomAPI_Ax3>& theBasePlane)
52 : myPlane(new Geom_Plane(theBasePlane->impl<gp_Ax3>())),
56 void setRadius(const double theRadius)
57 { myRadius = theRadius; }
59 void addCenter(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter)
60 { myCenter = theCenter; }
62 void addPassingEntity(const std::shared_ptr<GeomAPI_Interface>& theEntity)
64 std::shared_ptr<GeomAPI_Pnt2d> aPoint = std::dynamic_pointer_cast<GeomAPI_Pnt2d>(theEntity);
66 addPassingPoint(aPoint);
68 std::shared_ptr<GeomAPI_Shape> aShape = std::dynamic_pointer_cast<GeomAPI_Shape>(theEntity);
70 addTangentCurve(aShape);
74 void addTangentCurve(const std::shared_ptr<GeomAPI_Shape>& theEdge)
76 if (!theEdge->isEdge())
79 const TopoDS_Edge& anEdge = TopoDS::Edge(theEdge->impl<TopoDS_Shape>());
83 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, myPlane, aLoc, aFirst, aLast);
84 CurveAdaptorPtr aCurveAdaptor(new Geom2dAdaptor_Curve(aCurve, aFirst, aLast));
86 myTangentShapes.push_back(aCurveAdaptor);
89 void addPassingPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
91 myPassingPoints.push_back(thePoint->impl<gp_Pnt2d>());
96 if (myTangentShapes.size() > 1)
99 gp_Circ2d* aResult = 0;
101 if (myPassingPoints.size() == 1)
102 aResult = circleByCenterAndPassingPoint();
103 else if (myTangentShapes.size() == 1)
104 aResult = circleByCenterAndTangent();
105 else if (myRadius > 0.0)
106 aResult = circleByCenterAndRadius();
107 } else if (myRadius > 0.0) {
108 if (myTangentShapes.size() == 2)
109 aResult = circleByRadiusAndTwoTangentCurves();
111 switch (myPassingPoints.size()) {
113 aResult = circleByThreeTangentCurves();
116 aResult = circleByPointAndTwoTangentCurves();
119 aResult = circleByTwoPointsAndTangentCurve();
122 aResult = circleByThreePassingPoints();
132 void sortTangentShapes()
134 // sort tangent shapes, so circles go before lines
135 int aSize = (int)myTangentShapes.size();
136 for (int i = 1; i < aSize; ++i) {
137 if (myTangentShapes[i]->GetType() != GeomAbs_Circle)
140 for (int j = i - 1; j >= 0 && myTangentShapes[j]->GetType() == GeomAbs_Line; --j)
141 std::swap(myTangentShapes[j], myTangentShapes[j+1]);
145 gp_Circ2d* circleByCenterAndRadius()
147 const gp_Pnt2d& aCenter = myCenter->impl<gp_Pnt2d>();
148 return new gp_Circ2d(gp_Ax2d(aCenter, gp::DX2d()), myRadius);
151 gp_Circ2d* circleByCenterAndPassingPoint()
153 const gp_Pnt2d& aCenter = myCenter->impl<gp_Pnt2d>();
154 GccAna_Circ2dTanCen aBuilder(myPassingPoints[0], aCenter);
155 if (aBuilder.NbSolutions() > 0)
156 return new gp_Circ2d(aBuilder.ThisSolution(1));
160 gp_Circ2d* circleByCenterAndTangent()
162 const gp_Pnt2d& aCenter = myCenter->impl<gp_Pnt2d>();
163 CurveAdaptorPtr aCurve = myTangentShapes[0];
165 std::shared_ptr<GccAna_Circ2dTanCen> aCircleBuilder;
166 if (aCurve->GetType() == GeomAbs_Line) {
167 aCircleBuilder = std::shared_ptr<GccAna_Circ2dTanCen>(
168 new GccAna_Circ2dTanCen(aCurve->Line(), aCenter));
169 } else if (aCurve->GetType() == GeomAbs_Circle) {
170 aCircleBuilder = std::shared_ptr<GccAna_Circ2dTanCen>(new GccAna_Circ2dTanCen(
171 GccEnt::Unqualified(aCurve->Circle()), aCenter, Precision::Confusion()));
174 return getProperCircle(aCircleBuilder);
177 gp_Circ2d* getProperCircle(const std::shared_ptr<GccAna_Circ2dTanCen>& theBuilder) const
182 CurveAdaptorPtr aCurve = myTangentShapes[0];
184 gp_Circ2d* aResult = 0;
185 int aNbSol = theBuilder->NbSolutions();
186 double aParSol, aPonTgCurve;
188 for (int i = 1; i <= aNbSol && aCurve; ++i) {
189 theBuilder->Tangency1(i, aParSol, aPonTgCurve, aTgPnt);
190 if (aPonTgCurve >= aCurve->FirstParameter() && aPonTgCurve <= aCurve->LastParameter()) {
191 aResult = new gp_Circ2d(theBuilder->ThisSolution(i));
195 // unable to build circle passing through the tangent curve,
196 // so get a circle passing any tangent point
197 if (!aResult && aNbSol > 0)
198 aResult = new gp_Circ2d(theBuilder->ThisSolution(1));
203 gp_Circ2d* circleByThreeTangentCurves()
205 VectorOfGccCirc aTgCirc;
206 VectorOfGccLine aTgLine;
207 convertTangentCurvesToGccEnt(aTgCirc, aTgLine);
209 if (aTgCirc.size() + aTgLine.size() != 3)
212 std::shared_ptr<GccAna_Circ2d3Tan> aCircleBuilder;
213 switch (aTgLine.size()) {
215 aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
216 *aTgCirc[0], *aTgCirc[1], *aTgCirc[2], Precision::Confusion()));
219 aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
220 *aTgCirc[0], *aTgCirc[1], *aTgLine[0], Precision::Confusion()));
223 aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
224 *aTgCirc[0], *aTgLine[0], *aTgLine[1], Precision::Confusion()));
227 aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
228 *aTgLine[0], *aTgLine[1], *aTgLine[0], Precision::Confusion()));
234 return getProperCircle(aCircleBuilder);
237 gp_Circ2d* circleByPointAndTwoTangentCurves()
239 const gp_Pnt2d& aPoint = myPassingPoints[0];
240 CurveAdaptorPtr aCurve1 = myTangentShapes[0];
241 CurveAdaptorPtr aCurve2 = myTangentShapes[1];
242 if (!aCurve1 || !aCurve2)
245 std::shared_ptr<GccAna_Circ2d3Tan> aCircleBuilder;
246 if (aCurve1->GetType() == GeomAbs_Line) {
247 if (aCurve2->GetType() == GeomAbs_Line) {
248 aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(
249 new GccAna_Circ2d3Tan(GccEnt::Unqualified(aCurve1->Line()),
250 GccEnt::Unqualified(aCurve2->Line()),
251 aPoint, Precision::Confusion()));
252 } else if (aCurve2->GetType() == GeomAbs_Circle) {
253 aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(
254 new GccAna_Circ2d3Tan(GccEnt::Unqualified(aCurve2->Circle()),
255 GccEnt::Unqualified(aCurve1->Line()),
256 aPoint, Precision::Confusion()));
258 } else if (aCurve1->GetType() == GeomAbs_Circle) {
259 if (aCurve2->GetType() == GeomAbs_Line) {
260 aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(
261 new GccAna_Circ2d3Tan(GccEnt::Unqualified(aCurve1->Circle()),
262 GccEnt::Unqualified(aCurve2->Line()),
263 aPoint, Precision::Confusion()));
264 } else if (aCurve2->GetType() == GeomAbs_Circle) {
265 aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(
266 new GccAna_Circ2d3Tan(GccEnt::Unqualified(aCurve2->Circle()),
267 GccEnt::Unqualified(aCurve1->Circle()),
268 aPoint, Precision::Confusion()));
272 return getProperCircle(aCircleBuilder);
275 gp_Circ2d* circleByTwoPointsAndTangentCurve()
277 const gp_Pnt2d& aPoint1 = myPassingPoints[0];
278 const gp_Pnt2d& aPoint2 = myPassingPoints[1];
279 CurveAdaptorPtr aCurve = myTangentShapes[0];
283 std::shared_ptr<GccAna_Circ2d3Tan> aCircleBuilder;
284 if (aCurve->GetType() == GeomAbs_Line) {
285 aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
286 GccEnt::Unqualified(aCurve->Line()), aPoint1, aPoint2, Precision::Confusion()));
287 } else if (aCurve->GetType() == GeomAbs_Circle) {
288 aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
289 GccEnt::Unqualified(aCurve->Circle()), aPoint1, aPoint2, Precision::Confusion()));
292 return getProperCircle(aCircleBuilder);
295 gp_Circ2d* circleByThreePassingPoints()
297 GccAna_Circ2d3Tan aCircleBuilder(myPassingPoints[0],
300 Precision::Confusion());
301 if (aCircleBuilder.NbSolutions() > 0)
302 return new gp_Circ2d(aCircleBuilder.ThisSolution(1));
306 gp_Circ2d* getProperCircle(const std::shared_ptr<GccAna_Circ2d3Tan>& theBuilder) const
311 gp_Circ2d* aResult = 0;
312 int aNbSol = theBuilder->NbSolutions();
313 double aParSol, aPonTgCurve;
315 for (int i = 1; i <= aNbSol; ++i) {
316 bool isApplicable = false;
317 if (myTangentShapes.size() >= 1) {
318 theBuilder->Tangency1(i, aParSol, aPonTgCurve, aTgPnt);
319 isApplicable = aPonTgCurve >= myTangentShapes[0]->FirstParameter() &&
320 aPonTgCurve <= myTangentShapes[0]->LastParameter();
322 if (myTangentShapes.size() >= 2 && isApplicable) {
323 theBuilder->Tangency2(i, aParSol, aPonTgCurve, aTgPnt);
324 isApplicable = aPonTgCurve >= myTangentShapes[1]->FirstParameter() &&
325 aPonTgCurve <= myTangentShapes[1]->LastParameter();
327 if (myTangentShapes.size() >= 3 && isApplicable) {
328 theBuilder->Tangency3(i, aParSol, aPonTgCurve, aTgPnt);
329 isApplicable = aPonTgCurve >= myTangentShapes[2]->FirstParameter() &&
330 aPonTgCurve <= myTangentShapes[2]->LastParameter();
334 aResult = new gp_Circ2d(theBuilder->ThisSolution(i));
338 // unable to build circle passing through the tangent curve => get any tangent point
339 if (!aResult && aNbSol > 0)
340 aResult = new gp_Circ2d(theBuilder->ThisSolution(1));
345 gp_Circ2d* circleByRadiusAndTwoTangentCurves()
347 VectorOfGccCirc aTgCirc;
348 VectorOfGccLine aTgLine;
349 convertTangentCurvesToGccEnt(aTgCirc, aTgLine);
351 if (aTgCirc.size() + aTgLine.size() != 2)
354 std::shared_ptr<GccAna_Circ2d2TanRad> aCircleBuilder;
355 switch (aTgLine.size()) {
357 aCircleBuilder = std::shared_ptr<GccAna_Circ2d2TanRad>(new GccAna_Circ2d2TanRad(
358 *aTgCirc[0], *aTgCirc[1], myRadius, Precision::Confusion()));
361 aCircleBuilder = std::shared_ptr<GccAna_Circ2d2TanRad>(new GccAna_Circ2d2TanRad(
362 *aTgCirc[0], *aTgLine[0], myRadius, Precision::Confusion()));
365 aCircleBuilder = std::shared_ptr<GccAna_Circ2d2TanRad>(new GccAna_Circ2d2TanRad(
366 *aTgLine[0], *aTgLine[1], myRadius, Precision::Confusion()));
372 return getProperCircle(aCircleBuilder);
375 gp_Circ2d* getProperCircle(const std::shared_ptr<GccAna_Circ2d2TanRad>& theBuilder) const
380 gp_Circ2d* aResult = 0;
381 int aNbSol = theBuilder->NbSolutions();
382 double aParSol, aPonTgCurve;
384 for (int i = 1; i <= aNbSol; ++i) {
385 bool isApplicable = false;
386 if (myTangentShapes.size() >= 1) {
387 theBuilder->Tangency1(i, aParSol, aPonTgCurve, aTgPnt);
388 isApplicable = isParamInCurve(aPonTgCurve, myTangentShapes[0]);
390 if (myTangentShapes.size() >= 2 && isApplicable) {
391 theBuilder->Tangency2(i, aParSol, aPonTgCurve, aTgPnt);
392 isApplicable = isParamInCurve(aPonTgCurve, myTangentShapes[1]);
396 aResult = new gp_Circ2d(theBuilder->ThisSolution(i));
400 // unable to build circle passing through the tangent curve => get any tangent point
401 if (!aResult && aNbSol > 0)
402 aResult = new gp_Circ2d(theBuilder->ThisSolution(1));
407 void convertTangentCurvesToGccEnt(VectorOfGccCirc& theTangentCircles,
408 VectorOfGccLine& theTangentLines)
410 theTangentCircles.reserve(3);
411 theTangentLines.reserve(3);
413 std::vector<CurveAdaptorPtr>::iterator anIt = myTangentShapes.begin();
414 for (; anIt != myTangentShapes.end(); ++anIt) {
415 switch ((*anIt)->GetType()) {
417 theTangentLines.push_back(
418 std::shared_ptr<GccEnt_QualifiedLin>(
419 new GccEnt_QualifiedLin((*anIt)->Line(), GccEnt_unqualified))
423 theTangentCircles.push_back(
424 std::shared_ptr<GccEnt_QualifiedCirc>(
425 new GccEnt_QualifiedCirc((*anIt)->Circle(), GccEnt_unqualified))
435 // boundary parameters of curve are NOT applied
436 static bool isParamInCurve(double& theParameter, const CurveAdaptorPtr& theCurve)
438 if (theCurve->Curve()->IsPeriodic()) {
439 theParameter = ElCLib::InPeriod(theParameter,
440 theCurve->FirstParameter(),
441 theCurve->FirstParameter() + theCurve->Period());
443 return theParameter > theCurve->FirstParameter() &&
444 theParameter < theCurve->LastParameter();
447 // boundary parameters of curve are applied too
448 static bool isParamOnCurve(double& theParameter, const CurveAdaptorPtr& theCurve)
450 if (theCurve->IsPeriodic()) {
451 theParameter = ElCLib::InPeriod(theParameter,
452 theCurve->FirstParameter(),
453 theCurve->FirstParameter() + theCurve->Period());
455 return theParameter >= theCurve->FirstParameter() &&
456 theParameter <= theCurve->LastParameter();
460 Handle(Geom_Plane) myPlane;
461 std::shared_ptr<GeomAPI_Pnt2d> myCenter;
462 std::vector<gp_Pnt2d> myPassingPoints;
463 std::vector<CurveAdaptorPtr> myTangentShapes;
467 typedef std::shared_ptr<CircleBuilder> CircleBuilderPtr;
470 static gp_Circ2d* newCirc2d(const double theCenterX, const double theCenterY, const gp_Dir2d theDir,
471 const double theRadius)
473 gp_Pnt2d aCenter(theCenterX, theCenterY);
474 return new gp_Circ2d(gp_Ax2d(aCenter, theDir), theRadius);
477 static gp_Circ2d* newCirc2d(const double theCenterX, const double theCenterY,
478 const double thePointX, const double thePointY)
480 gp_Pnt2d aCenter(theCenterX, theCenterY);
481 gp_Pnt2d aPoint(thePointX, thePointY);
483 double aRadius = aCenter.Distance(aPoint);
485 if (aCenter.IsEqual(aPoint, Precision::Confusion()))
488 gp_Dir2d aDir(thePointX - theCenterX, thePointY - theCenterY);
490 return newCirc2d(theCenterX, theCenterY, aDir, aRadius);
493 static gp_Circ2d* newCirc2d(const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
494 const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint,
495 const std::shared_ptr<GeomAPI_Pnt2d>& theThirdPoint)
497 gp_XY aFirstPnt(theFirstPoint->x(), theFirstPoint->y());
498 gp_XY aSecondPnt(theSecondPoint->x(), theSecondPoint->y());
499 gp_XY aThirdPnt(theThirdPoint->x(), theThirdPoint->y());
501 gp_XY aVec12 = aSecondPnt - aFirstPnt;
502 gp_XY aVec23 = aThirdPnt - aSecondPnt;
503 gp_XY aVec31 = aFirstPnt - aThirdPnt;
505 // coefficients to calculate center
506 double aCoeff1, aCoeff2, aCoeff3;
508 // square of parallelogram
509 double aSquare2 = aVec12.Crossed(aVec23);
510 aSquare2 *= aSquare2 * 2.0;
511 if (aSquare2 < 1.e-20) {
512 // if two points are equal, build a circle on two different points as on diameter
513 double aSqLen12 = aVec12.SquareModulus();
514 double aSqLen23 = aVec23.SquareModulus();
515 double aSqLen31 = aVec31.SquareModulus();
516 if (aSqLen12 < Precision::SquareConfusion() &&
517 aSqLen23 < Precision::SquareConfusion() &&
518 aSqLen31 < Precision::SquareConfusion())
520 aCoeff1 = aCoeff2 = aCoeff3 = 1.0 / 3.0;
523 aCoeff1 = aVec23.Dot(aVec23) / aSquare2 * aVec12.Dot(aVec31.Reversed());
524 aCoeff2 = aVec31.Dot(aVec31) / aSquare2 * aVec23.Dot(aVec12.Reversed());
525 aCoeff3 = aVec12.Dot(aVec12) / aSquare2 * aVec31.Dot(aVec23.Reversed());
528 gp_XY aCenter = aFirstPnt * aCoeff1 + aSecondPnt * aCoeff2 + aThirdPnt * aCoeff3;
530 double aRadius = (aFirstPnt - aCenter).Modulus();
532 gp_Dir2d aDir(aFirstPnt - aCenter);
533 return newCirc2d(aCenter.X(), aCenter.Y(), aDir, aRadius);
538 GeomAPI_Circ2d::GeomAPI_Circ2d(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
539 const std::shared_ptr<GeomAPI_Pnt2d>& theCirclePoint)
541 newCirc2d(theCenter->x(), theCenter->y(), theCirclePoint->x(), theCirclePoint->y()))
545 GeomAPI_Circ2d::GeomAPI_Circ2d(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
546 const std::shared_ptr<GeomAPI_Dir2d>& theDir, double theRadius)
548 newCirc2d(theCenter->x(), theCenter->y(), theDir->impl<gp_Dir2d>(), theRadius))
552 GeomAPI_Circ2d::GeomAPI_Circ2d(const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
553 const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint,
554 const std::shared_ptr<GeomAPI_Pnt2d>& theThirdPoint)
555 : GeomAPI_Interface(newCirc2d(theFirstPoint, theSecondPoint, theThirdPoint))
559 GeomAPI_Circ2d::GeomAPI_Circ2d(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
560 const std::shared_ptr<GeomAPI_Shape>& theTangent,
561 const std::shared_ptr<GeomAPI_Ax3>& thePlane)
563 CircleBuilderPtr aBuilder(new CircleBuilder(thePlane));
564 aBuilder->addCenter(theCenter);
565 aBuilder->addTangentCurve(theTangent);
566 setImpl(aBuilder->circle());
569 GeomAPI_Circ2d::GeomAPI_Circ2d(const std::shared_ptr<GeomAPI_Interface>& theEntity1,
570 const std::shared_ptr<GeomAPI_Interface>& theEntity2,
571 const std::shared_ptr<GeomAPI_Interface>& theEntity3,
572 const std::shared_ptr<GeomAPI_Ax3>& thePlane)
574 CircleBuilderPtr aBuilder(new CircleBuilder(thePlane));
575 aBuilder->addPassingEntity(theEntity1);
576 aBuilder->addPassingEntity(theEntity2);
577 aBuilder->addPassingEntity(theEntity3);
578 setImpl(aBuilder->circle());
581 GeomAPI_Circ2d::GeomAPI_Circ2d(const std::shared_ptr<GeomAPI_Interface>& theEntity1,
582 const std::shared_ptr<GeomAPI_Interface>& theEntity2,
583 const double theRadius,
584 const std::shared_ptr<GeomAPI_Ax3>& thePlane)
586 CircleBuilderPtr aBuilder(new CircleBuilder(thePlane));
587 aBuilder->addPassingEntity(theEntity1);
588 aBuilder->addPassingEntity(theEntity2);
589 aBuilder->setRadius(theRadius);
590 setImpl(aBuilder->circle());
595 const std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Circ2d::project(
596 const std::shared_ptr<GeomAPI_Pnt2d>& thePoint) const
598 std::shared_ptr<GeomAPI_Pnt2d> aResult;
602 const gp_Pnt2d& aCenter = MY_CIRC2D->Location();
603 const gp_Pnt2d& aPoint = thePoint->impl<gp_Pnt2d>();
605 double aDist = aCenter.Distance(aPoint);
606 if (aDist < Precision::Confusion())
609 if (Abs(aDist - MY_CIRC2D->Radius()) < Precision::Confusion()) {
610 // Point on the circle
611 aResult = std::shared_ptr<GeomAPI_Pnt2d>(
612 new GeomAPI_Pnt2d(thePoint->x(), thePoint->y()));
614 gp_Dir2d aDir(aPoint.XY() - aCenter.XY());
615 gp_XY aNewPoint = aCenter.XY() + aDir.XY() * MY_CIRC2D->Radius();
616 aResult = std::shared_ptr<GeomAPI_Pnt2d>(
617 new GeomAPI_Pnt2d(aNewPoint.X(), aNewPoint.Y()));
623 const std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Circ2d::center() const
626 return std::shared_ptr<GeomAPI_Pnt2d>();
627 const gp_Pnt2d& aCenter = MY_CIRC2D->Location();
628 return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aCenter.X(), aCenter.Y()));
631 double GeomAPI_Circ2d::radius() const
635 return MY_CIRC2D->Radius();
638 //=================================================================================================
639 const bool GeomAPI_Circ2d::parameter(const std::shared_ptr<GeomAPI_Pnt2d> thePoint,
640 const double theTolerance,
641 double& theParameter) const
643 Handle(Geom2d_Circle) aCurve = new Geom2d_Circle(*MY_CIRC2D);
644 return GeomLib_Tool::Parameter(aCurve, thePoint->impl<gp_Pnt2d>(),
645 theTolerance, theParameter) == Standard_True;
648 //=================================================================================================
649 void GeomAPI_Circ2d::D0(const double theU, std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
651 Handle(Geom2d_Circle) aCurve = new Geom2d_Circle(*MY_CIRC2D);
653 aCurve->D0(theU, aPnt);
654 thePoint.reset(new GeomAPI_Pnt2d(aPnt.X(), aPnt.Y()));