예제 #1
0
        public IEventPoint Pop()
        {
            IEventPoint next = eventQueue.Pop();

            if (intersectionsToIgnore.Contains(next))
            {
                return(Pop());
            }
            return(next);
        }
예제 #2
0
        public bool IsEmpty()
        {
            if (eventQueue.IsEmpty())
            {
                return(true);
            }
            IEventPoint next = eventQueue.Peek();

            if (intersectionsToIgnore.Contains(next))
            {
                eventQueue.Pop();
                return(IsEmpty());
            }
            return(false);
        }
        internal Dictionary <Point, VoronoiCellUnorganised> WithPoints(IEnumerable <Point> points)
        {
            if (points.Count() == 0)
            {
                throw new System.ArgumentException("No points provided");
            }

            cells = new Dictionary <Point, VoronoiCellUnorganised>();

            // We'll start at the top of the field and work down.

            // Initialise the beachline with all points having most Y coordinate.
            // There'll often be only one of these, but calculating their interactions
            // with no background beachline is more difficult so it helps to include them all at once.

            HashSet <Point>     distinctPoints = new HashSet <Point>(points);
            List <Point>        highestPoints  = FindHighestPoints(distinctPoints).OrderBy(p => p.x).ToList();
            float               mostY          = highestPoints.First().y;
            IEnumerable <Point> otherPoints    = distinctPoints.Where(p => p.y < mostY);

            List <BeachSection> initialBeachSections = new List <BeachSection>();

            for (int i = 0; i < highestPoints.Count; i++)
            {
                Point left  = null;
                Point right = null;
                Point focus = highestPoints[i];
                cells[focus] = new VoronoiCellUnorganised(focus);
                if (i > 0)
                {
                    left = highestPoints[i - 1];
                    cells[focus].AddBorder(left);
                }

                if (i + 1 < highestPoints.Count)
                {
                    right = highestPoints[i + 1];
                    cells[focus].AddBorder(right);
                }

                BeachSection bs = new BeachSection(focus, left, right);
                initialBeachSections.Add(bs);
            }

            BeachLine beachLine = new BeachLine(initialBeachSections, otherPoints);

            // For the remaining points that don't lie on the initial beachline, handle them in descending order
            // of their y coordinate.

            while (beachLine.HasMoreEvents())
            {
                IEventPoint eventPoint = beachLine.PopEvent();

                if (eventPoint.EventType() == "Site")
                {
                    Point site = eventPoint.Point();

                    BeachSection containingBeachSection = beachLine.BeachSectionContainingPoint(site);

                    VoronoiCellUnorganised cell = new VoronoiCellUnorganised(site);
                    cells[site] = cell;
                    AddBorderBetweenCells(site, containingBeachSection.focus);

                    beachLine.SplitBeachSection(site);
                }
                else // EventType = "Intersect"
                {
                    IntersectEventPoint intersectEventPoint = (IntersectEventPoint)eventPoint;

                    BeachSection consumedBeachSection = intersectEventPoint.consumedBeachSection;

                    AddBorderBetweenCells(consumedBeachSection.leftBoundary, consumedBeachSection.rightBoundary);

                    beachLine.ConsumeBeachSection(intersectEventPoint);
                }
            }
            return(cells);
        }
예제 #4
0
 public void Remove(IEventPoint eventPoint)
 {
     intersectionsToIgnore.Add(eventPoint);
 }
예제 #5
0
 public void Add(IEventPoint eventPoint)
 {
     eventQueue.Add(eventPoint);
 }