diff --git a/src/clipper/clipper.cpp b/src/clipper/clipper.cpp index 518b4b7c353..4d7a40726fc 100644 --- a/src/clipper/clipper.cpp +++ b/src/clipper/clipper.cpp @@ -108,6 +108,10 @@ inline cInt Round(double val) return static_cast((val < 0) ? (val - 0.5) : (val + 0.5)); } +// Overriding the Eigen operators because we don't want to compare Z coordinate if IntPoint is 3 dimensional. +inline bool operator==(const IntPoint &l, const IntPoint &r) { return l.x() == r.x() && l.y() == r.y(); } +inline bool operator!=(const IntPoint &l, const IntPoint &r) { return l.x() != r.x() || l.y() != r.y(); } + //------------------------------------------------------------------------------ // PolyTree methods ... //------------------------------------------------------------------------------ @@ -178,19 +182,25 @@ double Area(const Path &poly) } //------------------------------------------------------------------------------ -double Area(const OutRec &outRec) +double Area(const OutPt *op) { - OutPt *op = outRec.Pts; + const OutPt *startOp = op; if (!op) return 0; double a = 0; do { a += (double)(op->Prev->Pt.x() + op->Pt.x()) * (double)(op->Prev->Pt.y() - op->Pt.y()); op = op->Next; - } while (op != outRec.Pts); + } while (op != startOp); return a * 0.5; } //------------------------------------------------------------------------------ +double Area(const OutRec &outRec) +{ + return Area(outRec.Pts); +} +//------------------------------------------------------------------------------ + bool PointIsVertex(const IntPoint &Pt, OutPt *pp) { OutPt *pp2 = pp; @@ -524,27 +534,32 @@ bool FirstIsBottomPt(const OutPt* btmPt1, const OutPt* btmPt2) p = btmPt2->Next; while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Next; double dx2n = std::fabs(GetDx(btmPt2->Pt, p->Pt)); - return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n); + + if (std::max(dx1p, dx1n) == std::max(dx2p, dx2n) && + std::min(dx1p, dx1n) == std::min(dx2p, dx2n)) + return Area(btmPt1) > 0; //if otherwise identical use orientation + else + return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n); } //------------------------------------------------------------------------------ // Called by GetLowermostRec() OutPt* GetBottomPt(OutPt *pp) { - OutPt* dups = 0; + OutPt* dups = nullptr; OutPt* p = pp->Next; while (p != pp) { if (p->Pt.y() > pp->Pt.y()) { pp = p; - dups = 0; + dups = nullptr; } else if (p->Pt.y() == pp->Pt.y() && p->Pt.x() <= pp->Pt.x()) { if (p->Pt.x() < pp->Pt.x()) { - dups = 0; + dups = nullptr; pp = p; } else { @@ -565,6 +580,7 @@ OutPt* GetBottomPt(OutPt *pp) } return pp; } + //------------------------------------------------------------------------------ bool Pt2IsBetweenPt1AndPt3(const IntPoint &pt1,