From 6af9dc4d365e4f1066db9b888da0f4896edaa81f Mon Sep 17 00:00:00 2001 From: abn Date: Thu, 12 Apr 2018 11:20:42 +0200 Subject: [PATCH] Bug fix: SegSegIntersector::areColinears() was too tolerant. (non homogeneous comparison of eps and quadratic term) --- .../InterpKernelGeo2DEdgeArcCircle.cxx | 4 +-- .../InterpKernelGeo2DEdgeArcCircle.hxx | 13 ++++++---- .../Geometric2D/InterpKernelGeo2DEdgeLin.cxx | 8 +++++- .../MEDCouplingIntersectTest.py | 26 +++++++++++++++++++ 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx index 0ca8f1f3d..ba2d601e7 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx @@ -334,8 +334,8 @@ void ArcCSegIntersector::areOverlappedOrOnlyColinears(const Bounds *whereToFind, _cross= ((*(_e2.getStartNode()))[0]-center[0])*((*(_e2.getEndNode()))[1]-center[1])- ((*(_e2.getStartNode()))[1]-center[1])*((*(_e2.getEndNode()))[0]-center[0]); - _determinant=getE1().getRadius()*getE1().getRadius()/_drSq-_cross*_cross/(_drSq*_drSq); - if(_determinant>-2*QuadraticPlanarPrecision::getPrecision())//QuadraticPlanarPrecision::getPrecision()*QuadraticPlanarPrecision::getPrecision()*_drSq*_drSq/(2.*_dx*_dx)) + _determinant = (getE1().getRadius()*getE1().getRadius()-_cross*_cross/_drSq) / _drSq; + if(_determinant > -2*QuadraticPlanarPrecision::getPrecision())//QuadraticPlanarPrecision::getPrecision()*QuadraticPlanarPrecision::getPrecision()*_drSq*_drSq/(2.*_dx*_dx)) obviousNoIntersection=false; else obviousNoIntersection=true; diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx index 19559f9bc..436920c60 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx @@ -47,6 +47,9 @@ namespace INTERP_KERNEL double _dist; }; + /** + * Cross-type intersector: edge1 is the arc of circle, edge2 is the segment. + */ class INTERPKERNEL_EXPORT ArcCSegIntersector : public CrossTypeEdgeIntersector { public: @@ -60,11 +63,11 @@ namespace INTERP_KERNEL const EdgeArcCircle& getE1() const { return (const EdgeArcCircle&)_e1; } const EdgeLin& getE2() const { return (const EdgeLin&)_e2; } private: - double _dx; - double _dy; - double _drSq; - double _cross; - double _determinant; + double _dx; //!< X extent of the segment + double _dy; //!< Y extent of the segment + double _drSq; //!< Square of the norm of the seg + double _cross; //!< See areOverlappedOrOnlyColinears() + double _determinant; //!< See areOverlappedOrOnlyColinears() }; class INTERPKERNEL_EXPORT EdgeArcCircle : public Edge diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx index 5ab940348..01b522844 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx @@ -107,8 +107,14 @@ std::list< IntersectElement > SegSegIntersector::getIntersectionsCharacteristicV */ bool SegSegIntersector::areColinears() const { + Bounds b; + b.prepareForAggregation(); + b.aggregate(_e1.getBounds()); + b.aggregate(_e2.getBounds()); double determinant=_matrix[0]*_matrix[3]-_matrix[1]*_matrix[2]; - return fabs(determinant)