//------------------------------------------------------------------------------ private PolyPt FixupOutPolygon(PolyPt p, bool stripPointyEdgesOnly = false) { //FixupOutPolygon() - removes duplicate points and simplifies consecutive //parallel edges by removing the middle vertex. if (p == null) return null; PolyPt pp = p, result = p, lastOK = null; for (; ; ) { if (pp.prev == pp || pp.prev == pp.next) { DisposePolyPts(pp); return null; } //test for duplicate points and for same slope (cross-product) ... if (PointsEqual(pp.pt, pp.next.pt) || SlopesEqual(pp.prev.pt, pp.pt, pp.next.pt)) { lastOK = null; pp.prev.next = pp.next; pp.next.prev = pp.prev; PolyPt tmp = pp; if (pp == result) result = pp.prev; pp = pp.prev; tmp = null; } else if (pp == lastOK) break; else { if (lastOK == null) lastOK = pp; pp = pp.next; } } return result; }
//------------------------------------------------------------------------------ private void DisposePolyPts(PolyPt pp) { if (pp == null) return; PolyPt tmpPp = null; pp.prev.next = null; while (pp != null) { tmpPp = pp; pp = pp.next; tmpPp = null; } }
//------------------------------------------------------------------------------ private bool FindSegment(ref PolyPt pp, IntPoint pt1, IntPoint pt2) { if (pp == null) return false; PolyPt pp2 = pp; do { if (PointsEqual(pp.pt, pt1) && (PointsEqual(pp.next.pt, pt2) || PointsEqual(pp.prev.pt, pt2))) return true; pp = pp.next; } while (pp != pp2); return false; }
//------------------------------------------------------------------------------ private PolyPt AddPolyPt(TEdge4 e, IntPoint pt) { bool ToFront = (e.side == EdgeSide.esLeft); if( e.outIdx < 0 ) { PolyPt newPolyPt = new PolyPt(); newPolyPt.pt = pt; newPolyPt.isHole = IsHole(e); m_PolyPts.Add(newPolyPt); newPolyPt.next = newPolyPt; newPolyPt.prev = newPolyPt; e.outIdx = m_PolyPts.Count-1; return newPolyPt; } else { PolyPt pp = m_PolyPts[e.outIdx]; if (ToFront && PointsEqual(pt, pp.pt)) return pp; if (!ToFront && PointsEqual(pt, pp.prev.pt)) return pp.prev; PolyPt newPolyPt = new PolyPt(); newPolyPt.pt = pt; newPolyPt.isHole = pp.isHole; newPolyPt.next = pp; newPolyPt.prev = pp.prev; newPolyPt.prev.next = newPolyPt; pp.prev = newPolyPt; if (ToFront) m_PolyPts[e.outIdx] = newPolyPt; return newPolyPt; } }
//------------------------------------------------------------------------------ private void ReversePolyPtLinks(PolyPt pp) { PolyPt pp1; PolyPt pp2; pp1 = pp; do { pp2 = pp1.next; pp1.next = pp1.prev; pp1.prev = pp2; pp1 = pp2; } while (pp1 != pp); }
//------------------------------------------------------------------------------ private PolyPt PolygonBottom(PolyPt pp) { PolyPt p = pp.next; PolyPt result = pp; while (p != pp) { if (p.pt.Y > result.pt.Y) result = p; else if (p.pt.Y == result.pt.Y && p.pt.X < result.pt.X) result = p; p = p.next; } return result; }
//------------------------------------------------------------------------------ private bool IsClockwise(PolyPt pt) { Int64 area = 0; PolyPt startPt = pt; do { area += (Int64)pt.pt.X * pt.next.pt.Y - (Int64)pt.next.pt.X * pt.pt.Y; pt = pt.next; } while (pt != startPt); //area = area /2; return area > 0; //reverse of normal formula because assuming Y axis inverted }
//------------------------------------------------------------------------------ private PolyPt InsertPolyPtBetween(PolyPt p1, PolyPt p2, IntPoint pt) { PolyPt result = new PolyPt(); result.pt = pt; result.isHole = p1.isHole; if (p2 == p1.next) { p1.next = result; p2.prev = result; result.next = p2; result.prev = p1; } else { p2.next = result; p1.prev = result; result.next = p1; result.prev = p2; } return result; }