Salome HOME
Task 2.1. Creation of ellipses and arcs of ellipse.
[modules/shaper.git] / src / GeomAPI / GeomAPI_Ellipse2d.cpp
diff --git a/src/GeomAPI/GeomAPI_Ellipse2d.cpp b/src/GeomAPI/GeomAPI_Ellipse2d.cpp
new file mode 100644 (file)
index 0000000..eca8f4a
--- /dev/null
@@ -0,0 +1,97 @@
+// Copyright (C) 2017-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAPI_Ellipse2d.cpp
+// Created:     26 April 2017
+// Author:      Artem ZHIDKOV
+
+#include <GeomAPI_Ellipse2d.h>
+#include <GeomAPI_Dir2d.h>
+#include <GeomAPI_Pnt2d.h>
+
+#include <gp_Ax22d.hxx>
+#include <gp_Elips2d.hxx>
+#include <Precision.hxx>
+
+#define MY_ELLIPSE implPtr<gp_Elips2d>()
+
+static gp_Elips2d* newEllipse(const gp_Pnt2d& theCenter,
+                              const gp_Dir2d& theXAxis,
+                              const double theMajorRadius,
+                              const double theMinorRadius)
+{
+  if (theMajorRadius < theMinorRadius - Precision::Confusion()) {
+    return newEllipse(theCenter, gp_Dir2d(-theXAxis.Y(), theXAxis.X()),
+                      theMinorRadius, theMajorRadius);
+  }
+
+  gp_Ax22d anAxis(theCenter, theXAxis);
+  return new gp_Elips2d(anAxis, theMajorRadius, theMinorRadius);
+}
+
+static gp_Elips2d* newEllipse(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
+                              const std::shared_ptr<GeomAPI_Pnt2d>& theAxisPoint,
+                              const std::shared_ptr<GeomAPI_Pnt2d>& thePassingPoint)
+{
+  const gp_Pnt2d& aCenter = theCenter->impl<gp_Pnt2d>();
+  const gp_Pnt2d& anAxisPnt = theAxisPoint->impl<gp_Pnt2d>();
+  const gp_Pnt2d& aPassedPnt = thePassingPoint->impl<gp_Pnt2d>();
+
+  gp_Dir2d aXAxis(anAxisPnt.XY() - aCenter.XY());
+  double aMajorRadius = anAxisPnt.Distance(aCenter);
+
+  gp_XY aPassedDir = aPassedPnt.XY() - aCenter.XY();
+
+  double X = aPassedDir.Dot(aXAxis.XY()) / aMajorRadius;
+  if (Abs(X) > 1.0 - Precision::Confusion())
+    return 0; // ellipse cannot be created for such parameters
+
+  double Y = aPassedDir.CrossMagnitude(aXAxis.XY());
+  double aMinorRadius = Y / Sqrt(1. - X * X);
+
+  return newEllipse(aCenter, aXAxis, aMajorRadius, aMinorRadius);
+}
+
+
+GeomAPI_Ellipse2d::GeomAPI_Ellipse2d(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
+                                     const std::shared_ptr<GeomAPI_Dir2d>& theXAxis,
+                                     const double theMajorRadius,
+                                     const double theMinorRadius)
+  : GeomAPI_Interface(newEllipse(theCenter->impl<gp_Pnt2d>(), theXAxis->impl<gp_Dir2d>(),
+                                 theMajorRadius, theMinorRadius))
+{
+}
+
+GeomAPI_Ellipse2d::GeomAPI_Ellipse2d(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
+                                     const std::shared_ptr<GeomAPI_Pnt2d>& theAxisPoint,
+                                     const std::shared_ptr<GeomAPI_Pnt2d>& thePassingPoint)
+  : GeomAPI_Interface(newEllipse(theCenter, theAxisPoint, thePassingPoint))
+{
+}
+
+std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Ellipse2d::center() const
+{
+  const gp_Pnt2d& aCenter = MY_ELLIPSE->Location();
+  return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aCenter.X(), aCenter.Y()));
+}
+
+std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Ellipse2d::firstFocus() const
+{
+  const gp_Pnt2d& aFirst = MY_ELLIPSE->Focus1();
+  return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aFirst.X(), aFirst.Y()));
+}
+
+std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Ellipse2d::secondFocus() const
+{
+  const gp_Pnt2d& aSecond = MY_ELLIPSE->Focus2();
+  return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aSecond.X(), aSecond.Y()));
+}
+
+double GeomAPI_Ellipse2d::minorRadius() const
+{
+  return MY_ELLIPSE->MinorRadius();
+}
+
+double GeomAPI_Ellipse2d::majorRadius() const
+{
+  return MY_ELLIPSE->MajorRadius();
+}