From 5c77969ab31483db346f702230c03bea90089a70 Mon Sep 17 00:00:00 2001 From: ageay Date: Thu, 31 Jan 2013 16:42:52 +0000 Subject: [PATCH] distance to mesh end of implementation --- src/INTERP_KERNEL/VolSurfUser.cxx | 53 ++++++++++++++++--- src/INTERP_KERNEL/VolSurfUser.hxx | 2 +- src/MEDCoupling/MEDCouplingUMesh.cxx | 3 +- src/MEDCoupling_Swig/MEDCouplingBasicsTest.py | 27 ++++++++++ 4 files changed, 75 insertions(+), 10 deletions(-) diff --git a/src/INTERP_KERNEL/VolSurfUser.cxx b/src/INTERP_KERNEL/VolSurfUser.cxx index 582d1c31a..288382500 100644 --- a/src/INTERP_KERNEL/VolSurfUser.cxx +++ b/src/INTERP_KERNEL/VolSurfUser.cxx @@ -19,13 +19,15 @@ // Author : Anthony Geay (CEA/DEN) #include "VolSurfUser.hxx" +#include "InterpKernelAutoPtr.hxx" #include #include +#include namespace INTERP_KERNEL { - double DistanceFromPtToSegInSpaceDim2(const double *pt, const double *pt0Seg2, const double *pt1Seg2) throw(INTERP_KERNEL::Exception) + double SquareDistanceFromPtToSegInSpaceDim2(const double *pt, const double *pt0Seg2, const double *pt1Seg2) throw(INTERP_KERNEL::Exception) { double dx=pt1Seg2[0]-pt0Seg2[0],dy=pt1Seg2[1]-pt0Seg2[1]; double norm=sqrt(dx*dx+dy*dy); @@ -37,7 +39,7 @@ namespace INTERP_KERNEL if(dotP<0. || dotP>norm) return std::numeric_limits::max(); double x=pt0Seg2[0]+dotP*dx,y=pt0Seg2[1]+dotP*dy; - return sqrt((x-pt[0])*(x-pt[0])+(y-pt[1])*(y-pt[1])); + return (x-pt[0])*(x-pt[0])+(y-pt[1])*(y-pt[1]); } double DistanceFromPtToTriInSpaceDim3(const double *pt, const double *pt0Tri3, const double *pt1Tri3, const double *pt2Tri3) throw(INTERP_KERNEL::Exception) @@ -56,12 +58,12 @@ namespace INTERP_KERNEL int nbOfHint=0; if(xy[0]>0. && xy[0]::max()) - { ret=std::min(ret,tmp); nbOfHint++; } - tmp=DistanceFromPtToSegInSpaceDim2(xy,xy2,xy0);//distance pt to edge [pt2Tri3,pt0Tri3] + { ret=std::min(ret,sqrt(z*z+tmp)); nbOfHint++; } + tmp=SquareDistanceFromPtToSegInSpaceDim2(xy,xy2,xy0);//distance pt to edge [pt2Tri3,pt0Tri3] if(tmp!=std::numeric_limits::max()) - { ret=std::min(ret,tmp); nbOfHint++; } + { ret=std::min(ret,sqrt(z*z+tmp)); nbOfHint++; } if(nbOfHint==3) ret=std::min(ret,fabs(z)); return ret; @@ -69,16 +71,51 @@ namespace INTERP_KERNEL double DistanceFromPtToPolygonInSpaceDim3(const double *pt, const int *connOfPolygonBg, const int *connOfPolygonEnd, const double *coords) throw(INTERP_KERNEL::Exception) { - return 0.; + std::size_t nbOfEdges=std::distance(connOfPolygonBg,connOfPolygonEnd); + if(nbOfEdges<3) + throw INTERP_KERNEL::Exception("DistanceFromPtToPolygonInSpaceDim3 : trying to compute a distance to a polygon containing less than 3 edges !"); + double baryOfNodes[3]={0.,0.,0.}; + for(std::size_t i=0;i(),1./((double)nbOfEdges))); + double matrix[12]; + if(!ComputeRotTranslationMatrixToPut3PointsOnOXY(coords+3*connOfPolygonBg[0],coords+3*connOfPolygonBg[1],baryOfNodes,matrix)) + return std::numeric_limits::max(); + INTERP_KERNEL::AutoPtr ptXY=new double[2*nbOfEdges]; ptXY[0]=0.; ptXY[1]=0.; + ptXY[2]=matrix[0]*coords[3*connOfPolygonBg[1]]+matrix[1]*coords[3*connOfPolygonBg[1]+1]+matrix[2]*coords[3*connOfPolygonBg[1]+2]+matrix[3]; ptXY[3]=0.; + for(std::size_t i=2;i::max(); + std::size_t nbOfHint=0; + for(std::size_t i=0;i::max()) + { ret=std::min(ret,sqrt(z*z+tmp)); nbOfHint++; } + } + if(nbOfHint==nbOfEdges) + ret=std::min(ret,fabs(z)); + return ret; } + /*! + * \param [out] matrix contain a dense matrix of size 12 with 3 rows containing each 4 colums. This matrix is the reduction of 4x4 matrix but the last + * line containing [0,0,0,1] is omitted. + */ bool ComputeRotTranslationMatrixToPut3PointsOnOXY(const double *p0, const double *p1, const double *p2, double *matrix) { double norm=sqrt((p1[0]-p0[0])*(p1[0]-p0[0])+(p1[1]-p0[1])*(p1[1]-p0[1])+(p1[2]-p0[2])*(p1[2]-p0[2])); double c=(p1[0]-p0[0])/norm; double s=sqrt(1-c*c); double y=p1[2]-p0[2],z=p0[1]-p1[1]; - norm=sqrt(y*y+z*z); y/=norm; z/=norm; + norm=sqrt(y*y+z*z); + if(norm!=0.) + { y/=norm; z/=norm; } double r0[9]={c,-z*s,y*s, z*s,y*y*(1-c)+c,y*z*(1-c), -y*s,z*y*(1-c),z*z*(1-c)+c}; diff --git a/src/INTERP_KERNEL/VolSurfUser.hxx b/src/INTERP_KERNEL/VolSurfUser.hxx index fea0f9886..20899dc59 100644 --- a/src/INTERP_KERNEL/VolSurfUser.hxx +++ b/src/INTERP_KERNEL/VolSurfUser.hxx @@ -38,7 +38,7 @@ namespace INTERP_KERNEL template void computeBarycenter2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim, double *res); - double DistanceFromPtToSegInSpaceDim2(const double *pt, const double *pt0Seg2, const double *pt1Seg2) throw(INTERP_KERNEL::Exception); + double SquareDistanceFromPtToSegInSpaceDim2(const double *pt, const double *pt0Seg2, const double *pt1Seg2) throw(INTERP_KERNEL::Exception); double DistanceFromPtToTriInSpaceDim3(const double *pt, const double *pt0Tri3, const double *pt1Tri3, const double *pt2Tri3) throw(INTERP_KERNEL::Exception); diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index 5401b44f6..232527ea8 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -3633,7 +3633,8 @@ void MEDCouplingUMesh::distanceToPoint2DCurveAlg(const double *pt, const DataArr { case INTERP_KERNEL::NORM_SEG2: { - double tmp=INTERP_KERNEL::DistanceFromPtToSegInSpaceDim2(pt,coords+2*ptr[ptrI[*zeCell]+1],coords+2*ptr[ptrI[*zeCell]+2]); + double tmp=INTERP_KERNEL::SquareDistanceFromPtToSegInSpaceDim2(pt,coords+2*ptr[ptrI[*zeCell]+1],coords+2*ptr[ptrI[*zeCell]+2]); + if(tmp!=std::numeric_limits::max()) tmp=sqrt(tmp); if(tmp