private NodeHalfEdge addEdge(Dictionary <Vector3, List <NodeHalfEdge> > edgesByStartPosition, NodeHalfEdge previous, Vector3 start, Vector3 end, Node node) { var currentEdge = new NodeHalfEdge { node = node }; if (!points.Contains(start)) { points.Add(start); } if (!points.Contains(end)) { points.Add(end); } currentEdge.destination = end; if (!edgesByStartPosition.ContainsKey(start)) { edgesByStartPosition.Add(start, new List <NodeHalfEdge>()); } edgesByStartPosition[start].Add(currentEdge); edges.Add(currentEdge); if (previous != null) { previous.next = currentEdge; currentEdge.previous = previous; } return(currentEdge); }
private void generateGraph(Voronoi voronoi) { points = new HashSet <Vector3>(); nodes = new HashSet <Node>(); edges = new List <NodeHalfEdge>(); var edgesByStartPosition = new Dictionary <Vector3, List <NodeHalfEdge> >(); var siteEdges = new Dictionary <Vector2, List <LineSegment> >(); foreach (var edge in voronoi.Edges()) { if (edge.visible) { 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) { 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); } } } foreach (var site in voronoi.SiteCoords()) { var boundries = getBoundriesForSite(siteEdges, site); var center = getPointWithElevation(site); var currentNode = new Node { centerPoint = center }; nodes.Add(currentNode); NodeHalfEdge firstEdge = null; NodeHalfEdge previousEdge = null; for (var i = 0; i < boundries.Count; i++) { var edge = boundries[i]; var start = getPointWithElevation(edge.p0.Value); var end = getPointWithElevation(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; } // figure out if the two edges meet, and if not then insert some more edges to close the polygon if (i < boundries.Count - 1) { start = getPointWithElevation(edge.p1.Value); end = getPointWithElevation(boundries[i + 1].p0.Value); } else if (i == boundries.Count - 1) { start = getPointWithElevation(edge.p1.Value); end = getPointWithElevation(boundries[0].p0.Value); } if (start != end) { previousEdge = addEdge(edgesByStartPosition, previousEdge, previousEdge.destination, end, currentNode); } } // Connect up the end of the loop previousEdge.next = firstEdge; firstEdge.previous = previousEdge; } connectOpposites(edgesByStartPosition); }