]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Welcome to DataArrayDouble::asArcOfCircle
authorAnthony Geay <anthony.geay@edf.fr>
Fri, 3 Nov 2017 15:23:13 +0000 (16:23 +0100)
committerAnthony Geay <anthony.geay@edf.fr>
Fri, 3 Nov 2017 15:23:13 +0000 (16:23 +0100)
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling_Swig/MEDCouplingBasicsTest6.py
src/MEDCoupling_Swig/MEDCouplingMemArray.i

index 91bef50389f19b4805a8f2d441ed511c2dd2aa22..17d15a485fb65c04c9ad80977ce7e860bb95189c 100644 (file)
 #include "InterpKernelAutoPtr.hxx"
 #include "InterpKernelExprParser.hxx"
 
+#include "InterpKernelAutoPtr.hxx"
+#include "InterpKernelGeo2DEdgeArcCircle.hxx"
+#include "InterpKernelAutoPtr.hxx"
+#include "InterpKernelGeo2DNode.hxx"
+#include "InterpKernelGeo2DEdgeLin.hxx"
+
 #include <set>
 #include <cmath>
 #include <limits>
@@ -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<INTERP_KERNEL::Node> 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<INTERP_KERNEL::EdgeLin> 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<INTERP_KERNEL::EdgeArcCircle> 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,
index bf8a15ff4aed6dfffa2a81b850bc9d3bb2983c15..313f9a7c8aaee907ae8167730615ef1ab49b5e2f 100644 (file)
@@ -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);
index 916e9c30c5762c2bb87dc243a134cdec847389ac..eb9a3930cbe9749407e692c70cebf72d9abe3748 100644 (file)
@@ -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__':
index ca7543efa7ce3f16080ad0328cd56d5dd96ef4ba..d7a5df027012fafbfa051a658ca88f0eb76cae5b 100644 (file)
@@ -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();