public void SplitBeachSection(Point site) { BeachSection containingBeachSection = BeachSectionContainingPoint(site); BeachSection newBeachSectionLeft = new BeachSection(containingBeachSection.focus, containingBeachSection.leftBoundary, site); BeachSection newBeachSectionCentre = new BeachSection(site, containingBeachSection.focus, containingBeachSection.focus); BeachSection newBeachSectionRight = new BeachSection(containingBeachSection.focus, site, containingBeachSection.rightBoundary); beachSections.Remove(containingBeachSection); beachSections.Add(newBeachSectionLeft); beachSections.Add(newBeachSectionCentre); beachSections.Add(newBeachSectionRight); foreach (IntersectEventPoint iep in IntersectEventPoint.FromBeachSections(new List <BeachSection> { newBeachSectionLeft, newBeachSectionRight })) { if (iep.Point().y <= site.y) { eventQueue.Add(iep); } } foreach (IntersectEventPoint iep in IntersectEventPoint.FromBeachSections(new List <BeachSection> { containingBeachSection })) { if (iep.Point().y <= site.y) { eventQueue.Remove(iep); } } }
public override bool Equals(object obj) { if (obj == null || GetType() != obj.GetType()) { return(false); } IntersectEventPoint that = (IntersectEventPoint)obj; List <Point> thisPoints = new List <Point> { a, b, c }; return(thisPoints.Contains(that.a) && thisPoints.Contains(that.b) && thisPoints.Contains(that.c)); }
public static HashSet <IntersectEventPoint> FromBeachSections(IEnumerable <BeachSection> beachSections) { HashSet <IntersectEventPoint> set = new HashSet <IntersectEventPoint>(); foreach (BeachSection bs in beachSections) { if (!bs.IsLeftmost() && !bs.IsRightmost() && bs.leftBoundary != bs.rightBoundary ) { Line lineA = bs.leftBoundary.LineWith(bs.rightBoundary); Line lineB = bs.leftBoundary.LineWith(bs.focus); if (!lineA.Equals(lineB) && bs.Closed()) { IntersectEventPoint iep = new IntersectEventPoint(bs); set.Add(iep); } } } return(set); }
public void ConsumeBeachSection(IntersectEventPoint intersectEventPoint) { BeachSection consumedBeachSection = intersectEventPoint.consumedBeachSection; BeachSection leftBeachSection = beachSections.Predecessor(consumedBeachSection); BeachSection rightBeachSection = beachSections.Successor(consumedBeachSection); BeachSection newLeftBeachSection = new BeachSection(leftBeachSection.focus, leftBeachSection.leftBoundary, rightBeachSection.focus); BeachSection newRightBeachSection = new BeachSection(rightBeachSection.focus, leftBeachSection.focus, rightBeachSection.rightBoundary); beachSections.Remove(consumedBeachSection); beachSections.Remove(leftBeachSection); beachSections.Remove(rightBeachSection); beachSections.Add(newLeftBeachSection); beachSections.Add(newRightBeachSection); foreach (IntersectEventPoint iep in IntersectEventPoint.FromBeachSections(new List <BeachSection> { leftBeachSection, rightBeachSection })) { if (iep.Point().y <= intersectEventPoint.Point().y) { eventQueue.Remove(iep); } } foreach (IntersectEventPoint iep in IntersectEventPoint.FromBeachSections(new List <BeachSection> { newLeftBeachSection, newRightBeachSection })) { if (iep.Point().y <= intersectEventPoint.Point().y) { if (!iep.Equals(intersectEventPoint)) { eventQueue.Add(iep); } } } }
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); }