From 4737cdf2ce045c40c7af9f35a41b20c733e583c0 Mon Sep 17 00:00:00 2001 From: Lev Dragunov Date: Mon, 19 Oct 2015 15:58:43 +0300 Subject: [routing] Cross section geometry generation fix. --- geometry/region2d.hpp | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) (limited to 'geometry') diff --git a/geometry/region2d.hpp b/geometry/region2d.hpp index 078c215445..7cf90d8560 100644 --- a/geometry/region2d.hpp +++ b/geometry/region2d.hpp @@ -29,11 +29,16 @@ namespace m2 my::AlmostEqualAbs(p1.y, p2.y, static_cast(kPrecision)); } template - bool EqualZero(TCoord val, TCoord) const + bool EqualZeroSquarePrecision(TCoord val) const { static_assert(std::is_floating_point::value, ""); - return my::AlmostEqualAbs(val, 0.0, static_cast(kPrecision)); + return my::AlmostEqualAbs(val, 0.0, kPrecision * kPrecision); + } + inline bool IsAlmostBetween(double val, double left, double right) const + { + return ((val >= left - kPrecision) && (val <= right + kPrecision)) || + ((val <= left + kPrecision) && (val >= right - kPrecision)); } }; @@ -45,10 +50,15 @@ namespace m2 return p1 == p2; } template - bool EqualZero(TCoord val, TCoord) const + bool EqualZeroSquarePrecision(TCoord val) const { return val == 0; } + inline bool IsAlmostBetween(double val, double left, double right) const + { + return ((val >= left) && (val <= right)) || + ((val <= left) && (val >= right)); + } }; template struct TraitsType; @@ -145,21 +155,23 @@ namespace m2 ContainerT Data() const { return m_points; } + template inline bool IsIntersect(CoordT const & x11, CoordT const & y11, CoordT const & x12, CoordT const & y12, - CoordT const & x21, CoordT const & y21, CoordT const & x22, CoordT const & y22, PointT & pt) const + CoordT const & x21, CoordT const & y21, CoordT const & x22, CoordT const & y22, + EqualF equalF, PointT & pt) const { if (!((y12 - y11) * (x22 - x21) - (x12 - x11) * (y22-y21))) return false; double v = ((x12 - x11) * (y21 - y11) + (y12 - y11) * (x11 - x21)) / ((y12 - y11) * (x22 - x21) - (x12 - x11) * (y22 - y21)); PointT p(x21 + (x22 - x21) * v, y21 + (y22 - y21) * v); - if (!(((p.x >= x11) && (p.x <= x12)) || ((p.x <= x11) && (p.x >= x12)))) + if (!equalF.IsAlmostBetween(p.x, x11, x12)) return false; - if (!(((p.x >= x21) && (p.x <= x22)) || ((p.x <= x21) && (p.x >= x22)))) + if (!equalF.IsAlmostBetween(p.x, x21, x22)) return false; - if (!(((p.y >= y11) && (p.y <= y12)) || ((p.y <= y11) && (p.y >= y12)))) + if (!equalF.IsAlmostBetween(p.y, y11, y12)) return false; - if (!(((p.y >= y21) && (p.y <= y22)) || ((p.y <= y21) && (p.y >= y22)))) + if (!equalF.IsAlmostBetween(p.y, y21, y22)) return false; pt = p; @@ -168,7 +180,7 @@ namespace m2 inline bool IsIntersect(PointT const & p1, PointT const & p2, PointT const & p3, PointT const & p4 , PointT & pt) const { - return IsIntersect(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, pt); + return IsIntersect(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, typename TraitsT::EqualType(), pt); } public: @@ -206,7 +218,7 @@ namespace m2 BigCoordT const delta = prev.y - curr.y; BigCoordT const cp = CrossProduct(curr, prev); - if (!equalF.EqualZero(cp, delta)) + if (!equalF.EqualZeroSquarePrecision(cp)) { bool const PrevGreaterCurr = delta > 0.0; -- cgit v1.2.3