private void InsertLocalMinima(LocalMinima newLm) { Contract.Requires(newLm != null); if (MinimaList == null) { MinimaList = newLm; } else if (newLm.Y >= MinimaList.Y) { newLm.Next = MinimaList; MinimaList = newLm; } else { var tmpLm = MinimaList; while (tmpLm.Next != null && (newLm.Y < tmpLm.Next.Y)) tmpLm = tmpLm.Next; newLm.Next = tmpLm.Next; tmpLm.Next = newLm; } }
private TEdge AddBoundsToLML(TEdge e) { Contract.Requires(e != null); Contract.Requires(e.Next != null); //Starting at the top of one bound we progress to the bottom where there's //a local minima. We then go to the top of the next bound. These two bounds //form the left and right (or right and left) bounds of the local minima. e.NextInLML = null; e = e.Next; for (; ; ) { if (e.Dx == HORIZONTAL) { //nb: proceed through horizontals when approaching from their right, // but break on horizontal minima if approaching from their left. // This ensures 'local minima' are always on the left of horizontals. if (e.Next.YTop < e.YTop && e.Next.XBot > e.Prev.XBot) break; if (e.XTop != e.Prev.XBot) SwapX(e); e.NextInLML = e.Prev; } else if (e.YCurr == e.Prev.YCurr) break; else e.NextInLML = e.Prev; e = e.Next; } //e and e.prev are now at a local minima ... var newLm = new LocalMinima { Next = null, Y = e.Prev.YBot }; if (e.Dx == HORIZONTAL) //horizontal edges never start a left bound { if (e.XBot != e.Prev.XBot) SwapX(e); newLm.LeftBound = e.Prev; newLm.RightBound = e; } else if (e.Dx < e.Prev.Dx) { newLm.LeftBound = e.Prev; newLm.RightBound = e; } else { newLm.LeftBound = e; newLm.RightBound = e.Prev; } newLm.LeftBound.Side = EdgeSide.Left; newLm.RightBound.Side = EdgeSide.Right; InsertLocalMinima(newLm); for (; ; ) { if (e.Next.YTop == e.YTop && e.Next.Dx != HORIZONTAL) break; e.NextInLML = e.Next; e = e.Next; if (e.Dx == HORIZONTAL && e.XBot != e.Prev.XTop) SwapX(e); } return e.Next; }
protected void PopLocalMinima() { if (CurrentLM == null) return; CurrentLM = CurrentLM.Next; }
protected virtual void Reset() { CurrentLM = MinimaList; //reset all edges ... var lm = MinimaList; while (lm != null) { var e = lm.LeftBound; while (e != null) { e.XCurr = e.XBot; e.YCurr = e.YBot; e.Side = EdgeSide.Left; e.OutIdx = -1; e = e.NextInLML; } e = lm.RightBound; while (e != null) { e.XCurr = e.XBot; e.YCurr = e.YBot; e.Side = EdgeSide.Right; e.OutIdx = -1; e = e.NextInLML; } lm = lm.Next; } }
// ReSharper disable once UnusedMemberHiearchy.Global // ReSharper disable once MemberCanBeProtected.Global public virtual void Clear() { MinimaList = null; MinimaList = null; Edges.Clear(); }