internal void Remove(Event @event) { var index = _list.IndexOfValue(@event); if (index != -1) { _list.RemoveAt(index); } }
public void Compute(HashSet<Point> points, int width, int height) { _root = null; _width = width; _height = height; if (points.Count < 2) { return; } Edges = new List<Edge>(); Cells = new List<Cell>(); _queue = new Queue(); foreach (Point point in points) { var @event = new Event(point, true); var cell = new Cell(point); point.Cell = cell; _queue.Enqueue(@event); Cells.Add(cell); } while (!_queue.IsEmpty()) { Event @event = _queue.Dequeue(); _ly = @event.Point.Y; if (@event.IsParabola) { InsertParabola(@event.Point); } else { RemoveParabola(@event); } _lasty = @event.Point.Y; } FinishEdge(_root); for (var i = 0; i < Edges.Count; i++) { if (Edges[i].Neighbour != null) { Edges[i].Start = Edges[i].Neighbour.End; } } }
internal void Enqueue(Event @event) { _list.Add(@event.Point.Y, @event); }
private void CheckCircle(Parabola b) { Parabola lp = GetLeftParent(b); Parabola rp = GetRightParent(b); Parabola a = GetLeftChild(lp); Parabola c = GetRightChild(rp); if (a == null || c == null || Equals(a.Site, c.Site)) return; Point s = GetEdgeIntersection(lp.Edge, rp.Edge); if (s == null) return; double d = Distance(a.Site, s); if (s.Y - d >= _ly) return; var e = new Event(new Point(s.X, s.Y - d), false); b.CircleEvent = e; e.Arch = b; _queue.Enqueue(e); }
private void RemoveParabola(Event e) { Parabola p1 = e.Arch; Parabola xl = GetLeftParent(p1); Parabola xr = GetRightParent(p1); Parabola p0 = GetLeftChild(xl); Parabola p2 = GetRightChild(xr); if (p0.CircleEvent != null) { _queue.Remove(p0.CircleEvent); p0.CircleEvent = null; } if (p2.CircleEvent != null) { _queue.Remove(p2.CircleEvent); p2.CircleEvent = null; } var p = new Point(e.Point.X, GetY(p1.Site, e.Point.X)); if (Equals(p0.Site.Cell.Last, p1.Site.Cell.First)) p1.Site.Cell.AddLeft(p); else p1.Site.Cell.AddRight(p); p0.Site.Cell.AddRight(p); p2.Site.Cell.AddLeft(p); _lasty = e.Point.Y; xl.Edge.End = p; xr.Edge.End = p; Parabola higher = null; Parabola par = p1; while (par != _root) { par = par.Parent; if (par == xl) { higher = xl; } if (par == xr) { higher = xr; } } higher.Edge = new Edge(p, p0.Site, p2.Site); Edges.Add(higher.Edge); Parabola gparent = p1.Parent.Parent; if (p1.Parent.Left == p1) { if (gparent.Left == p1.Parent) gparent.Left = p1.Parent.Right; else p1.Parent.Parent.Right = p1.Parent.Right; } else { if (gparent.Left == p1.Parent) gparent.Left = p1.Parent.Left; else gparent.Right = p1.Parent.Left; } CheckCircle(p0); CheckCircle(p2); }