Example #1
0
        private void build(List <VoronoiCell> cells, int lastMaxYIndex)
        {
            init(cells, lastMaxYIndex);

            // handle all
            while (_eventList.Count > 0)
            {
                FortuneEvent currentEvent = _eventList.First.Value;
                _eventList.RemoveFirst();
                switch (currentEvent.Kind)
                {
                case FortuneEvent.EventKind.Point:
                    handlePointEvent((FortunePointEvent)currentEvent);
                    break;

                case FortuneEvent.EventKind.Circle:
                    handleCircleEvent((FortuneCircleEvent)currentEvent);
                    break;
                }
            }

            // calculate the coordinates of the "free" sites
            _shoreLine.Finish(_rectangle, _startVerticalNodes);

            // remove degenerate edges
            clean(cells);
        }
Example #2
0
        private void addCircleEvent(FortuneEvent ev)
        {
            LinkedListNode <FortuneEvent> currentEvent = _eventList.First;

            while (currentEvent != null)
            {
                if (currentEvent.Value.Point.Y < ev.Point.Y)
                {
                    _eventList.AddBefore(currentEvent, ev);
                    return;
                }
                currentEvent = currentEvent.Next;
            }
            _eventList.AddLast(ev);
        }
Example #3
0
        private void handleCircleEvent(FortuneCircleEvent ev)
        {
            FortuneArc ln = ev.Arc.LeftNeighbor;
            FortuneArc rn = ev.Arc.RightNeighbor;

            // remove events range associated with this arc
            if (ln.CircleEvent != null)
            {
                _eventList.Remove(ln.CircleEvent);
            }
            if (rn.CircleEvent != null)
            {
                _eventList.Remove(rn.CircleEvent);
            }

            // remove the arc of coastline
            _shoreLine.RemoveArc(ev.Arc);

            //fix slave nodes arc ribs
            if (ev.Arc.LeftNode != null)
            {
                ev.Arc.LeftNode.Point     = ev.CircleCenter;
                ev.Arc.LeftNode.IsInfinit = false;
            }

            if (ev.Arc.RightNode != null)
            {
                ev.Arc.RightNode.Point     = ev.CircleCenter;
                ev.Arc.RightNode.IsInfinit = false;
            }

            // add a new edge
            VoronoiEdge edge = new VoronoiEdge(ln.Site.Cell, rn.Site.Cell);

            edge.Node1 = new VoronoiNode(ev.CircleCenter.X, ev.CircleCenter.Y);
            edge.Node2 = new VoronoiNode((ln.Site.Cell.DataPoint.X + rn.Site.Cell.DataPoint.X) / 2,
                                         (ln.Site.Cell.DataPoint.Y + rn.Site.Cell.DataPoint.Y) / 2);

            //expand the bounding rectangle of the chart
            _rectangle.Join(ev.CircleCenter);

            // one node of the new edge is fixed, the second - no
            edge.Node1.IsInfinit = false;
            edge.Node2.IsInfinit = true;

            // dobavleyaem edge to cells
            ln.Site.Cell.AddEdge(edge);
            rn.Site.Cell.AddEdge(edge);

            //add a triangle in the Delaunay triangulation, if necessary
            if (_buildTriangles)
            {
                _triangles.Add(ev.Triangle);
            }

            // not a fixed node is a new edge now vanished neighbors arc
            ln.RightNode = edge.Node2;
            rn.LeftNode  = edge.Node2;

            FortuneArc lnln = ln.LeftNeighbor;
            FortuneArc lnrn = ln.RightNeighbor;

            FortuneArc rnln = rn.LeftNeighbor;
            FortuneArc rnrn = rn.RightNeighbor;

            // add events to the newly formed circle arcs triples
            if (lnln != null)
            {
                if (lnrn != null)
                {
                    FortuneEvent eventToAdd = getCircleEvent(lnln, ln, lnrn, ev.Point.Y);
                    if (eventToAdd != null)
                    {
                        addCircleEvent(eventToAdd);
                    }
                    ln.CircleEvent = eventToAdd;
                }
            }

            if (rnln != null)
            {
                if (rnrn != null)
                {
                    FortuneEvent eventToAdd = getCircleEvent(rnln, rn, rnrn, ev.Point.Y);
                    if (eventToAdd != null)
                    {
                        addCircleEvent(eventToAdd);
                    }
                    rn.CircleEvent = eventToAdd;
                }
            }
        }
Example #4
0
        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;
                }
            }
        }