private void init(List <VoronoiCell> cells, int lastMaxYIndex) { _rectangle = new BoundingRectangle(); _eventList = new LinkedList <FortuneEvent>(); _startVerticalNodes = new List <VoronoiNode>(); // Where several points have the minimum ordinate requires a separate pre-treatment int skipEventCount = 0; if (lastMaxYIndex > 0) { VoronoiNode previousNode = null; FortuneArc currentArc = null; skipEventCount = lastMaxYIndex + 1; for (int i = 0; i <= lastMaxYIndex; i++) { // add an arc of coastline FortuneArc arc = new FortuneArc(); FortuneSite site = new FortuneSite(); site.Cell = cells[i]; arc.Site = site; if (currentArc != null) { currentArc.Right = arc; } currentArc = arc; if (_shoreLine.Root == null) { _shoreLine.Root = arc; } if (previousNode != null) { arc.LeftNode = previousNode; } // add the vertical edges of the Voronoi diagram if (i < lastMaxYIndex) { VoronoiEdge edge = new VoronoiEdge(cells[i], cells[i + 1]); double middleX = (cells[i].DataPoint.X + cells[i + 1].DataPoint.X) / 2; double middleY = cells[i].DataPoint.Y; edge.Node1 = new VoronoiNode(middleX, middleY); edge.Node1.IsInfinit = true; _startVerticalNodes.Add(edge.Node1); edge.Node2 = new VoronoiNode(middleX, middleY); edge.Node2.IsInfinit = true; previousNode = edge.Node2; arc.RightNode = edge.Node2; cells[i].AddEdge(edge); cells[i + 1].AddEdge(edge); } } } // fill all point events int j = 0; foreach (VoronoiCell cell in cells) { if (skipEventCount > j++) { continue; } FortunePointEvent ev = new FortunePointEvent(); ev.Point = cell.DataPoint; ev.Cell = cell; _eventList.AddLast(ev); } }
private void handlePointEvent(FortunePointEvent ev) { if (_shoreLine.Root == null) { FortuneArc arc = new FortuneArc(); FortuneSite site = new FortuneSite(); site.Cell = ev.Cell; arc.Site = site; _shoreLine.Root = arc; return; } FortuneArc arcAbove = _shoreLine.FindArc(ev.Point.X, ev.Point.Y); // remove events range from the queue if (arcAbove.CircleEvent != null) { _eventList.Remove(arcAbove.CircleEvent); } // create an arc FortuneArc splitter = new FortuneArc(); splitter.Site = new FortuneSite(); splitter.Site.Cell = ev.Cell; FortuneArc newArc = _shoreLine.SplitArc(arcAbove, splitter); FortuneArc ln = newArc.LeftNeighbor; FortuneArc lnln = null; if (ln != null) { lnln = ln.LeftNeighbor; } FortuneArc rn = newArc.RightNeighbor; FortuneArc rnrn = null; if (rn != null) { rnrn = rn.RightNeighbor; } if (ln != null) { if (lnln != null) { FortuneEvent eventToAdd = getCircleEvent(lnln, ln, newArc, ev.Point.Y); if (eventToAdd != null) { addCircleEvent(eventToAdd); } ln.CircleEvent = eventToAdd; } } if (rn != null) { if (rnrn != null) { FortuneEvent eventToAdd = getCircleEvent(newArc, rn, rnrn, ev.Point.Y); if (eventToAdd != null) { addCircleEvent(eventToAdd); } rn.CircleEvent = eventToAdd; } } }