예제 #1
0
        private FortuneEvent getCircleEvent(FortuneArc arc1,
                                            FortuneArc arc2,
                                            FortuneArc arc3,
                                            double y)
        {
            ICoordinate a = arc1.Site.Cell.DataPoint;
            ICoordinate b = arc2.Site.Cell.DataPoint;
            ICoordinate c = arc3.Site.Cell.DataPoint;

            //bc should turn to the right with respect to ab
            if ((b.X - a.X) * (c.Y - a.Y) - (c.X - a.X) * (b.Y - a.Y) > 0)
            {
                return(null);
            }

            ICoordinate point = getCircleCenter(a, b, c);

            if (point != null)
            {
                FortuneCircleEvent newEvent = new FortuneCircleEvent();
                newEvent.CircleCenter = point;

                double distance = PlanimetryAlgorithms.Distance(point, a);
                point = PlanimetryEnvironment.NewCoordinate(point.X, point.Y - distance);

                newEvent.Point = point;
                newEvent.Arc   = arc2;

                if (_buildTriangles)
                {
                    newEvent.Triangle = new Triangle(arc1.Site.Cell, arc2.Site.Cell, arc3.Site.Cell);
                }

                return(newEvent);
            }
            return(null);
        }
예제 #2
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;
                }
            }
        }