private TEdge AddBoundsToLML(TEdge E, bool Closed) { TEdge tEdge; if (E.OutIdx == -2) { if (this.MoreBelow(E)) { E = E.Next; tEdge = this.DescendToMin(ref E); } else { tEdge = null; } } else { tEdge = this.DescendToMin(ref E); } bool appending; if (E.OutIdx == -2) { this.DoMinimaLML(null, tEdge, Closed); appending = false; if (E.Bot != E.Prev.Bot && this.MoreBelow(E)) { E = E.Next; tEdge = this.DescendToMin(ref E); this.DoMinimaLML(tEdge, E, Closed); appending = true; } else if (this.JustBeforeLocMin(E)) { E = E.Next; } } else { this.DoMinimaLML(tEdge, E, Closed); appending = true; } this.AscendToMax(ref E, appending, Closed); if (E.OutIdx == -2 && E.Top != E.Prev.Top) { if (this.MoreAbove(E)) { E = E.Next; this.AscendToMax(ref E, false, Closed); } else if (E.Top == E.Next.Top || (ClipperBase.IsHorizontal(E.Next) && E.Top == E.Next.Bot)) { E = E.Next; } } return(E); }
private void DoMinimaLML(TEdge E1, TEdge E2, bool IsClosed) { if (E1 == null) { if (E2 == null) { return; } LocalMinima localMinima = new LocalMinima(); localMinima.Next = null; localMinima.Y = E2.Bot.Y; localMinima.LeftBound = null; E2.WindDelta = 0; localMinima.RightBound = E2; this.InsertLocalMinima(localMinima); } else { LocalMinima localMinima2 = new LocalMinima(); localMinima2.Y = E1.Bot.Y; localMinima2.Next = null; if (ClipperBase.IsHorizontal(E2)) { if (E2.Bot.X != E1.Bot.X) { this.ReverseHorizontal(E2); } localMinima2.LeftBound = E1; localMinima2.RightBound = E2; } else if (E2.Dx < E1.Dx) { localMinima2.LeftBound = E1; localMinima2.RightBound = E2; } else { localMinima2.LeftBound = E2; localMinima2.RightBound = E1; } localMinima2.LeftBound.Side = EdgeSide.esLeft; localMinima2.RightBound.Side = EdgeSide.esRight; if (!IsClosed) { localMinima2.LeftBound.WindDelta = 0; } else if (localMinima2.LeftBound.Next == localMinima2.RightBound) { localMinima2.LeftBound.WindDelta = -1; } else { localMinima2.LeftBound.WindDelta = 1; } localMinima2.RightBound.WindDelta = -localMinima2.LeftBound.WindDelta; this.InsertLocalMinima(localMinima2); } }
private TEdge GetLastHorz(TEdge Edge) { TEdge tEdge = Edge; while (tEdge.OutIdx != -2 && tEdge.Next != Edge && ClipperBase.IsHorizontal(tEdge.Next)) { tEdge = tEdge.Next; } return(tEdge); }
private TEdge DescendToMin(ref TEdge E) { E.NextInLML = null; if (ClipperBase.IsHorizontal(E)) { TEdge tEdge = E; while (ClipperBase.IsHorizontal(tEdge.Next)) { tEdge = tEdge.Next; } if (tEdge.Bot != tEdge.Next.Top) { this.ReverseHorizontal(E); } } while (true) { E = E.Next; if (E.OutIdx == -2) { break; } if (ClipperBase.IsHorizontal(E)) { TEdge tEdge = this.GetLastHorz(E); if (tEdge == E.Prev || (tEdge.Next.Top.Y < E.Top.Y && tEdge.Next.Bot.X > E.Prev.Bot.X)) { break; } if (E.Top.X != E.Prev.Bot.X) { this.ReverseHorizontal(E); } if (tEdge.OutIdx == -2) { tEdge = tEdge.Prev; } while (E != tEdge) { E.NextInLML = E.Prev; E = E.Next; if (E.Top.X != E.Prev.Bot.X) { this.ReverseHorizontal(E); } } } else if (E.Bot.Y == E.Prev.Bot.Y) { break; } E.NextInLML = E.Prev; } return(E.Prev); }
private bool MoreAbove(TEdge Edge) { if (ClipperBase.IsHorizontal(Edge)) { Edge = this.GetLastHorz(Edge); return(Edge.Next.Top.Y < Edge.Top.Y); } if (ClipperBase.IsHorizontal(Edge.Next)) { Edge = this.GetLastHorz(Edge.Next); return(Edge.Next.Top.Y < Edge.Top.Y); } return(Edge.Next.Top.Y < Edge.Top.Y); }
private bool JustBeforeLocMin(TEdge Edge) { TEdge tEdge = Edge; if (ClipperBase.IsHorizontal(tEdge)) { while (ClipperBase.IsHorizontal(tEdge.Next)) { tEdge = tEdge.Next; } return(tEdge.Next.Top.Y < tEdge.Bot.Y); } return(this.SharedVertWithNextIsBot(tEdge)); }
private bool AllHorizontal(TEdge Edge) { if (!ClipperBase.IsHorizontal(Edge)) { return(false); } for (TEdge next = Edge.Next; next != Edge; next = next.Next) { if (!ClipperBase.IsHorizontal(next)) { return(false); } } return(true); }
private bool MoreBelow(TEdge Edge) { TEdge tEdge = Edge; if (ClipperBase.IsHorizontal(tEdge)) { while (ClipperBase.IsHorizontal(tEdge.Next)) { tEdge = tEdge.Next; } return(tEdge.Next.Bot.Y > tEdge.Bot.Y); } if (ClipperBase.IsHorizontal(tEdge.Next)) { while (ClipperBase.IsHorizontal(tEdge.Next)) { tEdge = tEdge.Next; } return(tEdge.Next.Bot.Y > tEdge.Bot.Y); } return(tEdge.Bot == tEdge.Next.Top); }
private void AscendToMax(ref TEdge E, bool Appending, bool IsClosed) { if (E.OutIdx == -2) { E = E.Next; if (!this.MoreAbove(E.Prev)) { return; } } if (ClipperBase.IsHorizontal(E) && Appending && E.Bot != E.Prev.Bot) { this.ReverseHorizontal(E); } TEdge tEdge = E; while (E.Next.OutIdx != -2 && (E.Next.Top.Y != E.Top.Y || ClipperBase.IsHorizontal(E.Next))) { E.NextInLML = E.Next; E = E.Next; if (ClipperBase.IsHorizontal(E) && E.Bot.X != E.Prev.Top.X) { this.ReverseHorizontal(E); } } if (!Appending) { if (tEdge.OutIdx == -2) { tEdge = tEdge.Next; } if (tEdge != E.Next) { this.DoMinimaLML(null, tEdge, IsClosed); } } E = E.Next; }
public bool AddPath(List <IntPoint> pg, PolyType polyType, bool Closed) { if (!Closed) { throw new ClipperException("AddPath: Open paths have been disabled."); } int num = pg.Count - 1; bool flag = num > 0 && (Closed || pg[0] == pg[num]); while (num > 0 && pg[num] == pg[0]) { num--; } while (num > 0 && pg[num] == pg[num - 1]) { num--; } if ((Closed && num < 2) || (!Closed && num < 1)) { return(false); } List <TEdge> list = new List <TEdge>(num + 1); for (int i = 0; i <= num; i++) { list.Add(new TEdge()); } try { list[1].Curr = pg[1]; this.RangeTest(pg[0], ref this.m_UseFullRange); this.RangeTest(pg[num], ref this.m_UseFullRange); this.InitEdge(list[0], list[1], list[num], pg[0]); this.InitEdge(list[num], list[0], list[num - 1], pg[num]); for (int j = num - 1; j >= 1; j--) { this.RangeTest(pg[j], ref this.m_UseFullRange); this.InitEdge(list[j], list[j + 1], list[j - 1], pg[j]); } } catch { bool result = false; return(result); } TEdge tEdge = list[0]; if (!flag) { tEdge.Prev.OutIdx = -2; } TEdge tEdge2 = tEdge; TEdge tEdge3 = tEdge; while (true) { if (tEdge2.Curr == tEdge2.Next.Curr) { if (tEdge2 == tEdge2.Next) { break; } if (tEdge2 == tEdge) { tEdge = tEdge2.Next; } tEdge2 = this.RemoveEdge(tEdge2); tEdge3 = tEdge2; } else { if (tEdge2.Prev == tEdge2.Next) { break; } if ((flag || (tEdge2.Prev.OutIdx != -2 && tEdge2.OutIdx != -2 && tEdge2.Next.OutIdx != -2)) && ClipperBase.SlopesEqual(tEdge2.Prev.Curr, tEdge2.Curr, tEdge2.Next.Curr, this.m_UseFullRange) && Closed && (!this.PreserveCollinear || !this.Pt2IsBetweenPt1AndPt3(tEdge2.Prev.Curr, tEdge2.Curr, tEdge2.Next.Curr))) { if (tEdge2 == tEdge) { tEdge = tEdge2.Next; } tEdge2 = this.RemoveEdge(tEdge2); tEdge2 = tEdge2.Prev; tEdge3 = tEdge2; } else { tEdge2 = tEdge2.Next; if (tEdge2 == tEdge3) { break; } } } } if ((!Closed && tEdge2 == tEdge2.Next) || (Closed && tEdge2.Prev == tEdge2.Next)) { return(false); } this.m_edges.Add(list); if (!Closed) { this.m_HasOpenPaths = true; } TEdge tEdge4 = tEdge; tEdge2 = tEdge; do { this.InitEdge2(tEdge2, polyType); if (tEdge2.Top.Y < tEdge4.Top.Y) { tEdge4 = tEdge2; } tEdge2 = tEdge2.Next; }while (tEdge2 != tEdge); if (this.AllHorizontal(tEdge2)) { if (flag) { tEdge2.Prev.OutIdx = -2; } this.AscendToMax(ref tEdge2, false, false); return(true); } tEdge2 = tEdge.Prev; if (tEdge2.Prev == tEdge2.Next) { tEdge4 = tEdge2.Next; } else if (!flag && tEdge2.Top.Y == tEdge4.Top.Y) { if ((ClipperBase.IsHorizontal(tEdge2) || ClipperBase.IsHorizontal(tEdge2.Next)) && tEdge2.Next.Bot.Y == tEdge4.Top.Y) { tEdge4 = tEdge2.Next; } else if (this.SharedVertWithPrevAtTop(tEdge2)) { tEdge4 = tEdge2; } else if (tEdge2.Top == tEdge2.Prev.Top) { tEdge4 = tEdge2.Prev; } else { tEdge4 = tEdge2.Next; } } else { tEdge2 = tEdge4; while (ClipperBase.IsHorizontal(tEdge4) || tEdge4.Top == tEdge4.Next.Top || tEdge4.Top == tEdge4.Next.Bot) { tEdge4 = tEdge4.Next; if (tEdge4 == tEdge2) { while (ClipperBase.IsHorizontal(tEdge4) || !this.SharedVertWithPrevAtTop(tEdge4)) { tEdge4 = tEdge4.Next; } break; } } } tEdge2 = tEdge4; do { tEdge2 = this.AddBoundsToLML(tEdge2, Closed); }while (tEdge2 != tEdge4); return(true); }