Beispiel #1
0
    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));
    }
Beispiel #2
0
 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);
 }
Beispiel #3
0
    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);
    }