public IntPoint(DoublePoint dp) { this.X = (cInt)dp.X; this.Y = (cInt)dp.Y; this.Z = 0; }
public IntPoint(cInt X, cInt Y) { this.X = X; this.Y = Y; }
public IntPoint(cInt x, cInt y, cInt z = 0) { this.X = x; this.Y = y; this.Z = z; }
public IntPoint(double x, double y, double z = 0) { this.X = (cInt)x; this.Y = (cInt)y; this.Z = (cInt)z; }
//------------------------------------------------------------------------------ bool GetOverlap(cInt a1, cInt a2, cInt b1, cInt b2, out cInt Left, out cInt Right) { if (a1 < a2) { if (b1 < b2) {Left = Math.Max(a1,b1); Right = Math.Min(a2,b2);} else {Left = Math.Max(a1,b2); Right = Math.Min(a2,b1);} } else { if (b1 < b2) {Left = Math.Max(a2,b1); Right = Math.Min(a1,b2);} else { Left = Math.Max(a2, b2); Right = Math.Min(a1, b1); } } return Left < Right; }
//------------------------------------------------------------------------------ private void BuildIntersectList(cInt botY, cInt topY) { if ( m_ActiveEdges == null ) return; //prepare for sorting ... TEdge e = m_ActiveEdges; m_SortedEdges = e; while( e != null ) { e.PrevInSEL = e.PrevInAEL; e.NextInSEL = e.NextInAEL; e.Curr.X = TopX( e, topY ); e = e.NextInAEL; } //bubblesort ... bool isModified = true; while( isModified && m_SortedEdges != null ) { isModified = false; e = m_SortedEdges; while( e.NextInSEL != null ) { TEdge eNext = e.NextInSEL; IntPoint pt; if (e.Curr.X > eNext.Curr.X) { if (!IntersectPoint(e, eNext, out pt) && e.Curr.X > eNext.Curr.X +1) throw new ClipperException("Intersection error"); if (pt.Y > botY) { pt.Y = botY; if (Math.Abs(e.Dx) > Math.Abs(eNext.Dx)) pt.X = TopX(eNext, botY); else pt.X = TopX(e, botY); } InsertIntersectNode(e, eNext, pt); SwapPositionsInSEL(e, eNext); isModified = true; } else e = eNext; } if( e.PrevInSEL != null ) e.PrevInSEL.NextInSEL = null; else break; } m_SortedEdges = null; }
public IntRect(cInt l, cInt t, cInt r, cInt b) { this.left = l; this.top = t; this.right = r; this.bottom = b; }
//------------------------------------------------------------------------------ void GetHorzDirection(TEdge HorzEdge, out Direction Dir, out cInt Left, out cInt Right) { if (HorzEdge.Bot.X < HorzEdge.Top.X) { Left = HorzEdge.Bot.X; Right = HorzEdge.Top.X; Dir = Direction.dLeftToRight; } else { Left = HorzEdge.Top.X; Right = HorzEdge.Bot.X; Dir = Direction.dRightToLeft; } }
//------------------------------------------------------------------------------ private bool ProcessIntersections(cInt botY, cInt topY) { if( m_ActiveEdges == null ) return true; try { BuildIntersectList(botY, topY); if ( m_IntersectNodes == null) return true; if (m_IntersectNodes.Next == null || FixupIntersectionOrder()) ProcessIntersectList(); else return false; } catch { m_SortedEdges = null; DisposeIntersectNodes(); throw new ClipperException("ProcessIntersections error"); } m_SortedEdges = null; return true; }
//------------------------------------------------------------------------------ #endif private void InsertLocalMinimaIntoAEL(cInt botY) { while( m_CurrentLM != null && ( m_CurrentLM.Y == botY ) ) { TEdge lb = m_CurrentLM.LeftBound; TEdge rb = m_CurrentLM.RightBound; PopLocalMinima(); OutPt Op1 = null; if (lb == null) { InsertEdgeIntoAEL(rb, null); SetWindingCount(rb); if (IsContributing(rb)) Op1 = AddOutPt(rb, rb.Bot); } else { InsertEdgeIntoAEL(lb, null); InsertEdgeIntoAEL(rb, lb); SetWindingCount(lb); rb.WindCnt = lb.WindCnt; rb.WindCnt2 = lb.WindCnt2; if (IsContributing(lb)) Op1 = AddLocalMinPoly(lb, rb, lb.Bot); InsertScanbeam(lb.Top.Y); } if (IsHorizontal(rb)) AddEdgeToSEL(rb); else InsertScanbeam( rb.Top.Y ); if (lb == null) continue; //if output polygons share an Edge with a horizontal rb, they'll need joining later ... if (Op1 != null && IsHorizontal(rb) && m_GhostJoins.Count > 0 && rb.WindDelta != 0) { for (int i = 0; i < m_GhostJoins.Count; i++) { //if the horizontal Rb and a 'ghost' horizontal overlap, then convert //the 'ghost' join to a real join ready for later ... Join j = m_GhostJoins[i]; if (HorzSegmentsOverlap(j.OutPt1.Pt, j.OffPt, rb.Bot, rb.Top)) AddJoin(j.OutPt1, Op1, j.OffPt); } } if (lb.OutIdx >= 0 && lb.PrevInAEL != null && lb.PrevInAEL.Curr.X == lb.Bot.X && lb.PrevInAEL.OutIdx >= 0 && SlopesEqual(lb.PrevInAEL, lb, m_UseFullRange) && lb.WindDelta != 0 && lb.PrevInAEL.WindDelta != 0) { OutPt Op2 = AddOutPt(lb.PrevInAEL, lb.Bot); AddJoin(Op1, Op2, lb.Top); } if( lb.NextInAEL != rb ) { if (rb.OutIdx >= 0 && rb.PrevInAEL.OutIdx >= 0 && SlopesEqual(rb.PrevInAEL, rb, m_UseFullRange) && rb.WindDelta != 0 && rb.PrevInAEL.WindDelta != 0) { OutPt Op2 = AddOutPt(rb.PrevInAEL, rb.Bot); AddJoin(Op1, Op2, rb.Top); } TEdge e = lb.NextInAEL; if (e != null) while (e != rb) { //nb: For calculating winding counts etc, IntersectEdges() assumes //that param1 will be to the right of param2 ABOVE the intersection ... IntersectEdges(rb, e, lb.Curr); //order important here e = e.NextInAEL; } } } }
//------------------------------------------------------------------------------ private void InsertScanbeam(cInt Y) { if( m_Scanbeam == null ) { m_Scanbeam = new Scanbeam(); m_Scanbeam.Next = null; m_Scanbeam.Y = Y; } else if( Y > m_Scanbeam.Y ) { Scanbeam newSb = new Scanbeam(); newSb.Y = Y; newSb.Next = m_Scanbeam; m_Scanbeam = newSb; } else { Scanbeam sb2 = m_Scanbeam; while( sb2.Next != null && ( Y <= sb2.Next.Y ) ) sb2 = sb2.Next; if( Y == sb2.Y ) return; //ie ignores duplicates Scanbeam newSb = new Scanbeam(); newSb.Y = Y; newSb.Next = sb2.Next; sb2.Next = newSb; } }
public IntPoint(IntPoint pt) { this.X = pt.X; this.Y = pt.Y; this.Z = pt.Z; }
public IntPoint(double x, double y) { this.X = (cInt)x; this.Y = (cInt)y; }
//------------------------------------------------------------------------------ private static cInt TopX(TEdge edge, cInt currentY) { if (currentY == edge.Top.Y) return edge.Top.X; return edge.Bot.X + Round(edge.Dx *(currentY - edge.Bot.Y)); }
public IntPoint(IntPoint pt) { this.X = pt.X; this.Y = pt.Y; }
//------------------------------------------------------------------------------ private void ProcessEdgesAtTopOfScanbeam(cInt topY) { TEdge e = m_ActiveEdges; while(e != null) { //1. process maxima, treating them as if they're 'bent' horizontal edges, // but exclude maxima with horizontal edges. nb: e can't be a horizontal. bool IsMaximaEdge = IsMaxima(e, topY); if(IsMaximaEdge) { TEdge eMaxPair = GetMaximaPair(e); IsMaximaEdge = (eMaxPair == null || !IsHorizontal(eMaxPair)); } if(IsMaximaEdge) { TEdge ePrev = e.PrevInAEL; DoMaxima(e); if( ePrev == null) e = m_ActiveEdges; else e = ePrev.NextInAEL; } else { //2. promote horizontal edges, otherwise update Curr.X and Curr.Y ... if (IsIntermediate(e, topY) && IsHorizontal(e.NextInLML)) { UpdateEdgeIntoAEL(ref e); if (e.OutIdx >= 0) AddOutPt(e, e.Bot); AddEdgeToSEL(e); } else { e.Curr.X = TopX( e, topY ); e.Curr.Y = topY; } if (StrictlySimple) { TEdge ePrev = e.PrevInAEL; if ((e.OutIdx >= 0) && (e.WindDelta != 0) && ePrev != null && (ePrev.OutIdx >= 0) && (ePrev.Curr.X == e.Curr.X) && (ePrev.WindDelta != 0)) { OutPt op = AddOutPt(ePrev, e.Curr); OutPt op2 = AddOutPt(e, e.Curr); AddJoin(op, op2, e.Curr); //StrictlySimple (type-3) join } } e = e.NextInAEL; } } //3. Process horizontals at the Top of the scanbeam ... ProcessHorizontals(true); //4. Promote intermediate vertices ... e = m_ActiveEdges; while (e != null) { if(IsIntermediate(e, topY)) { OutPt op = null; if( e.OutIdx >= 0 ) op = AddOutPt(e, e.Top); UpdateEdgeIntoAEL(ref e); //if output polygons share an edge, they'll need joining later ... TEdge ePrev = e.PrevInAEL; TEdge eNext = e.NextInAEL; if (ePrev != null && ePrev.Curr.X == e.Bot.X && ePrev.Curr.Y == e.Bot.Y && op != null && ePrev.OutIdx >= 0 && ePrev.Curr.Y > ePrev.Top.Y && SlopesEqual(e, ePrev, m_UseFullRange) && (e.WindDelta != 0) && (ePrev.WindDelta != 0)) { OutPt op2 = AddOutPt(ePrev, e.Bot); AddJoin(op, op2, e.Top); } else if (eNext != null && eNext.Curr.X == e.Bot.X && eNext.Curr.Y == e.Bot.Y && op != null && eNext.OutIdx >= 0 && eNext.Curr.Y > eNext.Top.Y && SlopesEqual(e, eNext, m_UseFullRange) && (e.WindDelta != 0) && (eNext.WindDelta != 0)) { OutPt op2 = AddOutPt(eNext, e.Bot); AddJoin(op, op2, e.Top); } } e = e.NextInAEL; } }
public IntRect(IntRect ir) { this.left = ir.left; this.top = ir.top; this.right = ir.right; this.bottom = ir.bottom; }