public VoronoiBoundaryForSite ( Vector2 coord ) : List |
||
coord | Vector2 | |
return | List |
private void Demo() { List <uint> colors = new List <uint> (); m_points = new List <Vector2> (); for (int i = 0; i < m_pointCount; i++) { colors.Add(0); m_points.Add(new Vector2( UnityEngine.Random.Range(0, m_mapWidth), UnityEngine.Random.Range(0, m_mapHeight)) ); } Delaunay.Voronoi v = new Delaunay.Voronoi(m_points, colors, new Rect(0, 0, m_mapWidth, m_mapHeight)); m_edges = v.VoronoiDiagram(); m_spanningTree = v.SpanningTree(KruskalType.MINIMUM); m_delaunayTriangulation = v.DelaunayTriangulation(); tmpVBoundary = v.VoronoiBoundaryForSite(m_points[0]); }
void OnDrawGizmos() { if (v == null) { return; } Gizmos.color = Color.red; if (m_points != null) { for (int i = 0; i < m_points.Count; i++) { Gizmos.DrawSphere(m_points [i], 0.2f); } } if (DrawAllEdges) { if (m_edges != null) { Gizmos.color = Color.gray; for (int i = 0; i < m_edges.Count; i++) { Vector2 left = (Vector2)m_edges [i].p0; Vector2 right = (Vector2)m_edges [i].p1; Gizmos.DrawLine((Vector3)left, (Vector3)right); } } } if (DrawDelaunayTriangulation) { Gizmos.color = Color.magenta; if (m_delaunayTriangulation != null) { for (int i = 0; i < m_delaunayTriangulation.Count; i++) { Vector2 left = (Vector2)m_delaunayTriangulation [i].p0; Vector2 right = (Vector2)m_delaunayTriangulation [i].p1; Gizmos.DrawLine((Vector3)left, (Vector3)right); } } } if (DrawSpanningTree) { if (m_spanningTree != null) { Gizmos.color = Color.green; for (int i = 0; i < m_spanningTree.Count; i++) { LineSegment seg = m_spanningTree [i]; Vector2 left = (Vector2)seg.p0; Vector2 right = (Vector2)seg.p1; Gizmos.DrawLine((Vector3)left, (Vector3)right); } } } /** This is the correct source of Voronoi polygons: the "Regions" data from the Voronoi object. * Note that the list is points, not lines, and you usually have to manually CLOSE the final point to the first */ if (DrawVoronoiRegions) { Debug.Log("Found " + v.Regions().Count + " regions to draw"); foreach (List <Vector2> region in v.Regions()) { if (randomizeVoronoiColours) /** Note: the Edges display above (in Gray) shows unconnected edges, * but this section re-uses the actual semi-polygons created automatically by the Voronoi algorithm. To prove * this you can optionally turn on colourization of the edges, so that that shared edges will show with same colours */ { Gizmos.color = new Color(Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f)); } else { Gizmos.color = Color.white; } for (int i = 0; i + 1 < region.Count; i++) { Vector2 s = (Vector2)region [i]; Vector2 e = (Vector2)region [i + 1]; if (randomizeVoronoiColours) { /** To make them easier to see, shift the vectors SLIGHTLY towards the center point. * * REMoVED: WE CANT DO THAT WHEN USING THE REGIONS SHORTCUT, REGIONS DELETE THEIR POINTS, sadly :( * * This lets you see EXACTLY what poly / partial poly the algorithm is giving us "for free", * so that triangulating it will be easy in your own projects */ // s += (siteCoord - s) * 0.05f; // e += (siteCoord - e) * 0.05f; } Gizmos.DrawLine(s, e); } if (CloseExternalVoronoPolys) { Gizmos.DrawLine((Vector2)region [region.Count - 1], (Vector2)region [0]); } } } /** This is the INcorrect way of getting polygons out; but it has an advantage: the Voronoi class deletes * the Site at center of a Region when giving us Regions (bug: I'd like to fix that and have it return a data * structure that includes the Site!). * * In the meantime, here's how to manually generate the polys by re-using the Boundaries code from Voronoi, * much easier than trying to manually generate from raw edges. * * But ideally: use DrawVoronoiRegions instead */ if (DrawManualVoronoiPolygons) { /** Note, the SiteCoords are identical to the raw Points array you passed-in when creating the Voronoi object, * I think. So ... you could safely re-use that here instead of fetching it from the Voronoi object (maybe; could be * some filteing happening? Dupes removed, etc?) */ List <Vector2> ses = m_points; // v.SiteCoords (); foreach (Vector2 siteCoord in ses) { if (randomizeVoronoiColours) /** Note: the Edges display above (in Gray) shows unconnected edges, * but this section re-uses the actual semi-polygons created automatically by the Voronoi algorithm. To prove * this you can optionally turn on colourization of the edges, so that that shared edges will show with same colours */ { Gizmos.color = new Color(Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f)); } else { Gizmos.color = Color.white; } /** NB: this is the reason we had to change VoronoiDemo class and save the Voronoi object: the boundaries * are the Voronoi polygons, the most precious thing from the algorithm. They are saved as Regions data structure * when you run the algorithm - but that data structure throws-away the Site/Point that generates each Region. */ List <LineSegment> outlineOfSite = v.VoronoiBoundaryForSite(siteCoord); List <Vector2> pointsOnPolygonOutline = null; if (CloseExternalVoronoPolys) { pointsOnPolygonOutline = new List <Vector2> (); } foreach (LineSegment seg in outlineOfSite) { Vector2 s = (Vector2)seg.p0; Vector2 e = (Vector2)seg.p1; if (randomizeVoronoiColours) { /** To make them easier to see, shift the vectors SLIGHTLY towards the center point. * * This lets you see EXACTLY what poly / partial poly the algorithm is giving us "for free", * so that triangulating it will be easy in your own projects */ s += (siteCoord - s) * 0.05f; e += (siteCoord - e) * 0.05f; } Gizmos.DrawLine(s, e); if (CloseExternalVoronoPolys) { pointsOnPolygonOutline.Add(s); pointsOnPolygonOutline.Add(e); } } if (CloseExternalVoronoPolys) { List <Vector2> unduplicatedPoints = new List <Vector2> (); //Debug.Log( "Closing outline; "+pointsOnPolygonOutline.Count+" points on outline, with "+outlineOfSite.Count+" lines between them"); foreach (Vector2 point in pointsOnPolygonOutline) { Vector2 dupe; if ((dupe = ListContainsVectorCloseToVector(unduplicatedPoints, point)) != Vector2.zero) { //Debug.Log( " - point: "+point); unduplicatedPoints.Remove(dupe); } else { //Debug.Log( " + point: "+point); unduplicatedPoints.Add(point); } } if (unduplicatedPoints.Count == 2) { // two points that need connecting Gizmos.DrawLine(unduplicatedPoints [0], unduplicatedPoints [1]); } else if (unduplicatedPoints.Count > 1) { Debug.LogError("Should only have 0 or 2 unconnected points in a single polygon; had: " + unduplicatedPoints.Count); } } if (DrawManualVoronoiLinesToCenter) { foreach (LineSegment seg in outlineOfSite) { Gizmos.color = Color.gray; Gizmos.DrawLine((Vector2)seg.p0, siteCoord); } } } } if (DrawBounds) { Gizmos.color = Color.yellow; Gizmos.DrawLine(new Vector2(0, 0), new Vector2(0, m_mapHeight)); Gizmos.DrawLine(new Vector2(0, 0), new Vector2(m_mapWidth, 0)); Gizmos.DrawLine(new Vector2(m_mapWidth, 0), new Vector2(m_mapWidth, m_mapHeight)); Gizmos.DrawLine(new Vector2(0, m_mapHeight), new Vector2(m_mapWidth, m_mapHeight)); } }