//------------------------------------------------------------------------------ double Area(OutRec outRec, bool UseFull64BitRange) { OutPt op = outRec.pts; if (op == null) return 0; if (UseFull64BitRange) { Int128 a = new Int128(0); do { a += Int128.Int128Mul(op.pt.X + op.prev.pt.X, op.prev.pt.Y - op.pt.Y); op = op.next; } while (op != outRec.pts); return a.ToDouble() / 2; } else { double a = 0; do { a = a + (op.pt.X + op.prev.pt.X) * (op.prev.pt.Y - op.pt.Y); op = op.next; } while (op != outRec.pts); return a / 2; } }
//---------------------------------------------------------------------- private void FixupFirstLefts2(OutRec OldOutRec, OutRec NewOutRec) { foreach (OutRec outRec in m_PolyOuts) if (outRec.FirstLeft == OldOutRec) outRec.FirstLeft = NewOutRec; }
//------------------------------------------------------------------------------ private void UpdateOutPtIdxs(OutRec outrec) { OutPt op = outrec.pts; do { op.idx = outrec.idx; op = op.prev; } while (op != outrec.pts); }
//------------------------------------------------------------------------------ private void FixupOutPolygon(OutRec outRec) { //FixupOutPolygon() - removes duplicate points and simplifies consecutive //parallel edges by removing the middle vertex. OutPt lastOK = null; outRec.bottomPt = null; OutPt pp = outRec.pts; for (; ; ) { if (pp.prev == pp || pp.prev == pp.next) { DisposeOutPts(pp); outRec.pts = null; return; } //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, m_UseFullRange)) { lastOK = null; OutPt tmp = pp; pp.prev.next = pp.next; pp.next.prev = pp.prev; pp = pp.prev; tmp = null; } else if (pp == lastOK) break; else { if (lastOK == null) lastOK = pp; pp = pp.next; } } outRec.pts = pp; }
//---------------------------------------------------------------------- private void FixupFirstLefts1(OutRec OldOutRec, OutRec NewOutRec) { for (int i = 0; i < m_PolyOuts.Count; i++) { OutRec outRec = m_PolyOuts[i]; if (outRec.pts != null && outRec.FirstLeft == OldOutRec) { if (Poly2ContainsPoly1(outRec.pts, NewOutRec.pts, m_UseFullRange)) outRec.FirstLeft = NewOutRec; } } }
//------------------------------------------------------------------------------ bool Param1RightOfParam2(OutRec outRec1, OutRec outRec2) { do { outRec1 = outRec1.FirstLeft; if (outRec1 == outRec2) return true; } while (outRec1 != null); return false; }
//------------------------------------------------------------------------------ private OutRec GetLowermostRec(OutRec outRec1, OutRec outRec2) { //work out which polygon fragment has the correct hole state ... if (outRec1.bottomPt == null) outRec1.bottomPt = GetBottomPt(outRec1.pts); if (outRec2.bottomPt == null) outRec2.bottomPt = GetBottomPt(outRec2.pts); OutPt bPt1 = outRec1.bottomPt; OutPt bPt2 = outRec2.bottomPt; if (bPt1.pt.Y > bPt2.pt.Y) return outRec1; else if (bPt1.pt.Y < bPt2.pt.Y) return outRec2; else if (bPt1.pt.X < bPt2.pt.X) return outRec1; else if (bPt1.pt.X > bPt2.pt.X) return outRec2; else if (bPt1.next == bPt1) return outRec2; else if (bPt2.next == bPt2) return outRec1; else if (FirstIsBottomPt(bPt1, bPt2)) return outRec1; else return outRec2; }
//------------------------------------------------------------------------------ private void SetHoleState(TEdge e, OutRec outRec) { bool isHole = false; TEdge e2 = e.prevInAEL; while (e2 != null) { if (e2.outIdx >= 0) { isHole = !isHole; if (outRec.FirstLeft == null) outRec.FirstLeft = m_PolyOuts[e2.outIdx]; } e2 = e2.prevInAEL; } if (isHole) outRec.isHole = true; }
//------------------------------------------------------------------------------ private OutRec CreateOutRec() { OutRec result = new OutRec(); result.idx = -1; result.isHole = false; result.FirstLeft = null; result.pts = null; result.bottomPt = null; result.polyNode = null; m_PolyOuts.Add(result); result.idx = m_PolyOuts.Count - 1; return result; }
//------------------------------------------------------------------------------ internal void FixHoleLinkage(OutRec outRec) { //skip if an outermost polygon or //already already points to the correct FirstLeft ... if (outRec.FirstLeft == null || (outRec.isHole != outRec.FirstLeft.isHole && outRec.FirstLeft.pts != null)) return; OutRec orfl = outRec.FirstLeft; while (orfl != null && ((orfl.isHole == outRec.isHole) || orfl.pts == null)) orfl = orfl.FirstLeft; outRec.FirstLeft = orfl; }