From 0a1103e17eb5f47898af4e1509394b6ea4d6aba8 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Fri, 3 Nov 2017 16:23:13 +0100 Subject: [PATCH] Welcome to DataArrayDouble::asArcOfCircle --- src/MEDCoupling/MEDCouplingMemArray.cxx | 38 +++++++++++++++++++ src/MEDCoupling/MEDCouplingMemArray.hxx | 1 + .../MEDCouplingBasicsTest6.py | 10 ++++- src/MEDCoupling_Swig/MEDCouplingMemArray.i | 16 ++++++++ 4 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index 91bef5038..17d15a485 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -25,6 +25,12 @@ #include "InterpKernelAutoPtr.hxx" #include "InterpKernelExprParser.hxx" +#include "InterpKernelAutoPtr.hxx" +#include "InterpKernelGeo2DEdgeArcCircle.hxx" +#include "InterpKernelAutoPtr.hxx" +#include "InterpKernelGeo2DNode.hxx" +#include "InterpKernelGeo2DEdgeLin.hxx" + #include #include #include @@ -2489,6 +2495,38 @@ DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const Da return ret.retn(); } +/*! + * This method expects that \a this stores 3 tuples containing 2 components each. + * Each of this tuples represent a point into 2D space. + * This method tries to find an arc of circle starting from first point (tuple) to 2nd and middle point (tuple) along 3nd and last point (tuple). + * If such arc of circle exists, the corresponding center, radius of circle is returned. And additionnaly the length of arc expressed with an \a ang output variable in ]0,2*pi[. + * + * \throw If \a this is not allocated. + * \throw If \a this has not 3 tuples of 2 components + * \throw If tuples/points in \a this are aligned + */ +void DataArrayDouble::asArcOfCircle(double center[2], double& radius, double& ang) const +{ + checkAllocated(); + INTERP_KERNEL::QuadraticPlanarArcDetectionPrecision arcPrec(1e-14); + if(getNumberOfTuples()!=3 && getNumberOfComponents()!=2) + throw INTERP_KERNEL::Exception("DataArrayDouble::asArcCircle : this method expects"); + const double *pt(begin()); + MCAuto n0(new INTERP_KERNEL::Node(pt[0],pt[1])),n1(new INTERP_KERNEL::Node(pt[2],pt[3])),n2(new INTERP_KERNEL::Node(pt[4],pt[5])); + { + INTERP_KERNEL::AutoCppPtr e1(new INTERP_KERNEL::EdgeLin(n0,n2)),e2(new INTERP_KERNEL::EdgeLin(n2,n1)); + INTERP_KERNEL::SegSegIntersector inters(*e1,*e2); + bool colinearity(inters.areColinears()); + if(colinearity) + throw INTERP_KERNEL::Exception("DataArrayDouble::asArcOfCircle : 3 points in this have been detected as colinear !"); + } + INTERP_KERNEL::AutoCppPtr ret(new INTERP_KERNEL::EdgeArcCircle(n0,n2,n1)); + const double *c(ret->getCenter()); + center[0]=c[0]; center[1]=c[1]; + radius=ret->getRadius(); + ang=ret->getAngle(); +} + /*! * Sorts value within every tuple of \a this array. * \param [in] asc - if \a true, the values are sorted in ascending order, else, diff --git a/src/MEDCoupling/MEDCouplingMemArray.hxx b/src/MEDCoupling/MEDCouplingMemArray.hxx index bf8a15ff4..313f9a7c8 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.hxx +++ b/src/MEDCoupling/MEDCouplingMemArray.hxx @@ -470,6 +470,7 @@ namespace MEDCoupling MEDCOUPLING_EXPORT DataArrayDouble *maxPerTupleWithCompoId(DataArrayInt32* &compoIdOfMaxPerTuple) const; MEDCOUPLING_EXPORT DataArrayDouble *buildEuclidianDistanceDenseMatrix() const; MEDCOUPLING_EXPORT DataArrayDouble *buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const; + MEDCOUPLING_EXPORT void asArcOfCircle(double center[2], double& radius, double& ang) const; MEDCOUPLING_EXPORT void sortPerTuple(bool asc); MEDCOUPLING_EXPORT void applyInv(double numerator); MEDCOUPLING_EXPORT void applyPow(double val); diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest6.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest6.py index 916e9c30c..eb9a3930c 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest6.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest6.py @@ -158,7 +158,15 @@ class MEDCouplingBasicsTest6(unittest.TestCase): sla.deleteSimplePack(1) self.assertTrue(sla.getIndexArray().isEqual(DataArrayInt([0,2]))) self.assertTrue(sla.getValuesArray().isEqual(DataArrayInt([2,3]))) - pass + pass + + def testDADAsArcOfCircle(self): + d=DataArrayDouble([3.06915124862645,2.1464466094067824,2.85355345827285,2.3620444674400574,2.637955532559882,2.1464467447661937],3,2) + center,radius,ang=d.asArcOfCircle() + self.assertTrue((d-center).magnitude().isUniform(radius,1e-10)) + self.assertAlmostEqual(ang,-4.712389294301196,12) + pass + pass if __name__ == '__main__': diff --git a/src/MEDCoupling_Swig/MEDCouplingMemArray.i b/src/MEDCoupling_Swig/MEDCouplingMemArray.i index ca7543efa..d7a5df027 100644 --- a/src/MEDCoupling_Swig/MEDCouplingMemArray.i +++ b/src/MEDCoupling_Swig/MEDCouplingMemArray.i @@ -1045,6 +1045,22 @@ namespace MEDCoupling } } + PyObject *asArcOfCircle() const throw(INTERP_KERNEL::Exception) + { + double center[2],radius,ang; + self->asArcOfCircle(center,radius,ang); + PyObject *ret(PyTuple_New(3)); + { + PyObject *ret0(PyList_New(2)); + PyList_SetItem(ret0,0,PyFloat_FromDouble(center[0])); + PyList_SetItem(ret0,1,PyFloat_FromDouble(center[1])); + PyTuple_SetItem(ret,0,ret0); + } + PyTuple_SetItem(ret,1,PyFloat_FromDouble(radius)); + PyTuple_SetItem(ret,2,PyFloat_FromDouble(ang)); + return ret; + } + DataArrayDoubleIterator *__iter__() throw(INTERP_KERNEL::Exception) { return self->iterator(); -- 2.39.2