private void CreateHighlightEffect(double x, double y) { Point?point = _voronoi.NearestSitePoint(x, y); if (point.HasValue) { List <LineSegment> boundaries = _voronoi.VoronoiBoundaryForSite(point.Value); IEnumerable <Line> lines = ShapeSegments.Where(segment => segment is Line).Cast <Line>(); } }
private void CreateFromVoronoi(Voronoi voronoi) { vertices = new Dictionary <Vector3, Vertex>(); nodesByCenterPosition = new Dictionary <Vector3, Node>(); var edgesByStartPosition = new Dictionary <Vector3, List <Edge> >(); edges = new List <Edge>(); plotBounds = voronoi.plotBounds; var bottomLeftSite = voronoi.NearestSitePoint(plotBounds.xMin, plotBounds.yMin); var bottomRightSite = voronoi.NearestSitePoint(plotBounds.xMax, plotBounds.yMin); var topLeftSite = voronoi.NearestSitePoint(plotBounds.xMin, plotBounds.yMax); var topRightSite = voronoi.NearestSitePoint(plotBounds.xMax, plotBounds.yMax); var topLeft = new Vector3(plotBounds.xMin, 0, plotBounds.yMax); var topRight = new Vector3(plotBounds.xMax, 0, plotBounds.yMax); var bottomLeft = new Vector3(plotBounds.xMin, 0, plotBounds.yMin); var bottomRight = new Vector3(plotBounds.xMax, 0, plotBounds.yMin); var siteEdges = new Dictionary <Vector2, List <LineSegment> >(); var edgePointsRemoved = 0; foreach (var edge in voronoi.Edges()) { if (!edge.visible) { continue; } var p1 = edge.clippedEnds[Delaunay.LR.Side.LEFT]; var p2 = edge.clippedEnds[Delaunay.LR.Side.RIGHT]; var segment = new LineSegment(p1, p2); if (Vector2.Distance(p1.Value, p2.Value) < 0.001f) { edgePointsRemoved++; continue; } if (edge.leftSite != null) { if (!siteEdges.ContainsKey(edge.leftSite.Coord)) { siteEdges.Add(edge.leftSite.Coord, new List <LineSegment>()); } siteEdges[edge.leftSite.Coord].Add(segment); } if (edge.rightSite != null) { if (!siteEdges.ContainsKey(edge.rightSite.Coord)) { siteEdges.Add(edge.rightSite.Coord, new List <LineSegment>()); } siteEdges[edge.rightSite.Coord].Add(segment); } } Debug.Assert(edgePointsRemoved == 0, string.Format("{0} edge points too close and have been removed", edgePointsRemoved)); foreach (var site in voronoi.SiteCoords()) { var boundries = GetBoundriesForSite(siteEdges, site); var center = ToVector3(site); var currentNode = new Node { centerPoint = center }; nodesByCenterPosition.Add(center, currentNode); Edge firstEdge = null; Edge previousEdge = null; for (var i = 0; i < boundries.Count; i++) { var edge = boundries[i]; var start = ToVector3(edge.p0.Value); var end = ToVector3(edge.p1.Value); if (start == end) { continue; } previousEdge = AddEdge(edgesByStartPosition, previousEdge, start, end, currentNode); if (firstEdge == null) { firstEdge = previousEdge; } if (currentNode.startEdge == null) { currentNode.startEdge = previousEdge; } // We need to figure out if the two edges meet, and if not then // insert some more edges to close the polygon var insertEdges = false; if (i < boundries.Count - 1) { start = ToVector3(boundries[i + 0].p1.Value); end = ToVector3(boundries[i + 1].p0.Value); insertEdges = start != end; } else if (i == boundries.Count - 1) { start = ToVector3(boundries[i].p1.Value); end = ToVector3(boundries[0].p0.Value); insertEdges = start != end; } if (insertEdges) { // Check which corners are within this node var startIsTop = start.z == voronoi.plotBounds.yMax; var startIsBottom = start.z == voronoi.plotBounds.yMin; var startIsLeft = start.x == voronoi.plotBounds.xMin; var startIsRight = start.x == voronoi.plotBounds.xMax; var hasTopLeft = site == topLeftSite && !(startIsTop && startIsLeft); var hasTopRight = site == topRightSite && !(startIsTop && startIsRight); var hasBottomLeft = site == bottomLeftSite && !(startIsBottom && startIsLeft); var hasBottomRight = site == bottomRightSite && !(startIsBottom && startIsRight); if (startIsTop) { if (hasTopRight) { previousEdge = AddEdge(edgesByStartPosition, previousEdge, start, topRight, currentNode); } if (hasBottomRight) { previousEdge = AddEdge(edgesByStartPosition, previousEdge, previousEdge.destination.position, bottomRight, currentNode); } if (hasBottomLeft) { previousEdge = AddEdge(edgesByStartPosition, previousEdge, previousEdge.destination.position, bottomLeft, currentNode); } if (hasTopLeft) { previousEdge = AddEdge(edgesByStartPosition, previousEdge, previousEdge.destination.position, topLeft, currentNode); } } else if (startIsRight) { if (hasBottomRight) { previousEdge = AddEdge(edgesByStartPosition, previousEdge, start, bottomRight, currentNode); } if (hasBottomLeft) { previousEdge = AddEdge(edgesByStartPosition, previousEdge, previousEdge.destination.position, bottomLeft, currentNode); } if (hasTopLeft) { previousEdge = AddEdge(edgesByStartPosition, previousEdge, previousEdge.destination.position, topLeft, currentNode); } if (hasTopRight) { previousEdge = AddEdge(edgesByStartPosition, previousEdge, previousEdge.destination.position, topRight, currentNode); } } else if (startIsBottom) { if (hasBottomLeft) { previousEdge = AddEdge(edgesByStartPosition, previousEdge, start, bottomLeft, currentNode); } if (hasTopLeft) { previousEdge = AddEdge(edgesByStartPosition, previousEdge, previousEdge.destination.position, topLeft, currentNode); } if (hasTopRight) { previousEdge = AddEdge(edgesByStartPosition, previousEdge, previousEdge.destination.position, topRight, currentNode); } if (hasBottomRight) { previousEdge = AddEdge(edgesByStartPosition, previousEdge, previousEdge.destination.position, bottomRight, currentNode); } } else if (startIsLeft) { if (hasTopLeft) { previousEdge = AddEdge(edgesByStartPosition, previousEdge, start, topLeft, currentNode); } if (hasTopRight) { previousEdge = AddEdge(edgesByStartPosition, previousEdge, previousEdge.destination.position, topRight, currentNode); } if (hasBottomRight) { previousEdge = AddEdge(edgesByStartPosition, previousEdge, previousEdge.destination.position, bottomRight, currentNode); } if (hasBottomLeft) { previousEdge = AddEdge(edgesByStartPosition, previousEdge, previousEdge.destination.position, bottomLeft, currentNode); } } previousEdge = AddEdge(edgesByStartPosition, previousEdge, previousEdge.destination.position, end, currentNode); } } // Connect up the end of the loop previousEdge.next = firstEdge; firstEdge.previous = previousEdge; AddLeavingEdge(firstEdge); } ConnectOpposites(edgesByStartPosition); }