public override List <SubdividableEdgeLoop <CityEdge> > GetChildren(SubdividableEdgeLoop <CityEdge> parent) { Polygon parentPoly = parent.GetPolygon(); Path polygonAsClip = parentPoly.ClipperPath(HelperFunctions.clipperScale); EdgeLoopEdge[] edges = parent.GetEdges(); EdgeLoopEdge longestEdge = edges[0]; float longestEdgeLength = 0; parent.EnumerateEdges((EdgeLoopEdge edge) => { float edgeLength = Vector2.Distance(edge.a.pt, edge.b.pt); if (edgeLength > longestEdgeLength) { longestEdgeLength = edgeLength; longestEdge = edge; } }); Vector2 edgeDirection = longestEdge.b.pt - longestEdge.a.pt; float angle = Mathf.Atan2(edgeDirection.y, edgeDirection.x) * Mathf.Rad2Deg; Rect bounds = parentPoly.bounds; float maxDimension = Mathf.Max(bounds.width, bounds.height); bounds.width = maxDimension; bounds.height = maxDimension; Rect expandedBounds = new Rect(bounds.center - bounds.size * 0.55f, bounds.size * 1.1f); ILinkedGraphEdgeFactory <CityEdge> factory = new CityEdgeFactory(); List <DividingEdge> edgePaths = new List <DividingEdge>(); Vector2 centroid = parentPoly.centroid; float relativeBoundAngle = 0f; Rect parentRotatedBounds = HelperFunctions.GetOrientedBounds(new List <Vector2>(parentPoly.points), ref relativeBoundAngle); float rotation = relativeBoundAngle * Mathf.Rad2Deg; if (parentRotatedBounds.width > parentRotatedBounds.height * 0.7f) { //edgePaths.Add(new DividingEdge((centroid - Vector2.right * 1000f).RotatedAround(centroid, rotation), (centroid + Vector2.right * 1000f).RotatedAround(centroid, rotation), factory, factoryParams)); edgePaths.Add(new DividingEdge((centroid - Vector2.up * 1000f).RotatedAround(centroid, rotation), (centroid + Vector2.up * 1000f).RotatedAround(centroid, rotation), factory, factoryParams)); } if (parentRotatedBounds.height > parentRotatedBounds.width * 0.7f) { //edgePaths.Add(new DividingEdge((centroid - Vector2.up * 1000f).RotatedAround(centroid, rotation), (centroid + Vector2.up * 1000f).RotatedAround(centroid, rotation), factory, factoryParams)); edgePaths.Add(new DividingEdge((centroid - Vector2.right * 1000f).RotatedAround(centroid, rotation), (centroid + Vector2.right * 1000f).RotatedAround(centroid, rotation), factory, factoryParams)); } return(CollectChildren(parent, edgePaths)); }
public Vector2[] GetPoints() { Vector2[] points = new Vector2[edges.Count]; points[0] = edges[0].GetSharedVertex(edges[1]).pt; for (int i = 1; i < points.Length; i++) { EdgeLoopEdge edge = edges[i]; //ensure that each edge adds a unique point given the winding direction //is unknown if (edge.a.pt.Equals(points[i - 1])) { points[i] = edge.b.pt; } else { points[i] = edge.a.pt; } } return(points); }
public List <EdgeType> GetLocalLoop(EdgeType startingEdge, bool ccw) { List <EdgeType> foundEdges = new List <EdgeType>(); foundEdges.Add(startingEdge); LinkedGraphVertex firstVertex = startingEdge.a; LinkedGraphVertex lastVertex = startingEdge.b; bool foundLoop = false; int edgesSeen = 0; while (!foundLoop) { EdgeLoopEdge lastEdge = foundEdges[foundEdges.Count - 1]; Vector2 lastEdgeDirection = lastEdge.GetOppositeVertex(lastVertex).pt - lastVertex.pt; float minAngle = float.MaxValue; EdgeType minAngleEdge = null; if (lastVertex.NumConnections() <= 1) { Debug.LogWarning("Reached end of loop while collecting loop."); return(null); } foreach (LinkedGraphEdge connection in lastVertex.GetConnections()) { if (connection == lastEdge) { continue;//ignore the connection if it is this instance. } //all connections must share lastVertex with lastEdge Vector2 thisEdgeDirection = connection.GetOppositeVertex(lastVertex).pt - lastVertex.pt; float angle = HelperFunctions.AngleBetween(thisEdgeDirection, lastEdgeDirection); if (!ccw) { //we want to invert the smallest angle when its cw since angleBetween gets the ccw angle angle = Mathf.PI * 2 - angle; } if (angle < minAngle) { if (connection is EdgeType) { minAngle = angle; minAngleEdge = (EdgeType)connection; } else { Debug.LogWarning("Could not isolate loop because connected edges were not EdgeLoopEdges"); } } edgesSeen++; if (edgesSeen > MAXLOOPSIZE) { Debug.LogWarning("Couldn't close loop. Failing"); DebugLines debug = GameObject.FindObjectOfType <DebugLines>(); foreach (EdgeType edge in foundEdges) { debug.AddEdge(edge, Color.red); } return(null); } } foundEdges.Add(minAngleEdge); lastVertex = minAngleEdge.GetOppositeVertex(lastVertex); if (lastVertex == firstVertex) { foundLoop = true; } } //maintain the loops go ccw paradigm if (!ccw) { foundEdges.Reverse(); } return(foundEdges); }