Esempio n. 1
0
    public static EdgeType[] GetPolygonEdges(int sides, float radius, float radiusRandomness, float randomnessRangeDetail, ILinkedGraphEdgeFactory <EdgeType> factory, System.Object[] factoryParams)
    {
        LinkedGraphVertex[] verts = new LinkedGraphVertex[sides];
        EdgeType[]          edges = new EdgeType[sides];

        float noiseOffset = Random.value * 10000f;

        for (int i = 0; i < sides; i++)
        {
            float t     = (i / (float)sides);
            float angle = t * Mathf.PI * 2;

            Vector2 unitCircle  = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle));
            Vector2 position    = unitCircle * radius;
            float   noise       = Mathf.PerlinNoise(position.x / randomnessRangeDetail + noiseOffset, position.y / randomnessRangeDetail) - 0.5f;
            Vector2 modPosition = unitCircle * (radius + noise * radiusRandomness);
            verts[i] = new LinkedGraphVertex(modPosition);
        }

        for (int i = 0; i < sides; i++)
        {
            int firstVertInd  = i;
            int secondVertInd = (i + 1) % sides;
            edges[i] = factory.GetEdge(verts[firstVertInd], verts[secondVertInd], factoryParams);
        }
        return(edges);
    }
Esempio n. 2
0
    private static void DebugVert(LinkedGraphVertex vert)
    {
        Random.InitState(vert.GetHashCode());
        Color vCol = Color.red;
        float len  = 2f;

        if (vert.connections.Count == 1)
        {
            len = 10f;
        }
        else if (vert.connections.Count == 2)
        {
            vCol = Color.green;
        }
        else if (vert.connections.Count == 3)
        {
            vCol = Color.yellow;
        }
        else if (vert.connections.Count == 4)
        {
            vCol = Color.black;
        }
        else if (vert.connections.Count == 5)
        {
            vCol = Color.white;
        }
        else if (vert.connections.Count > 5)
        {
            vCol = Color.gray;
        }
        Debug.DrawLine(HelperFunctions.projVec2(vert.pt), HelperFunctions.projVec2(vert.pt) + (Vector3.up + new Vector3(Random.Range(-0.3f, 0.3f), 0, 0)) * len, vCol);
    }
Esempio n. 3
0
    //check to see if an edge in this loop follows the ccw
    public bool EdgeFollowsWinding(EdgeType edge)
    {
        int ind = edges.IndexOf(edge);

        if (ind == -1)
        {
            Debug.Log("Could not calculate if edge follows winding. Not part of loop.");
            return(false);
        }
        //get the vertex on first edge that is shared by the first two edges
        LinkedGraphVertex lastVertex = edges[0].GetSharedVertex(edges[1]);

        for (int i = 0; i < edges.Count; i++)
        {
            if (i > 0)
            {
                lastVertex = edges[i].GetOppositeVertex(lastVertex);
            }
            if (i == ind && edges[i].b == lastVertex)
            {
                return(true);
            }
        }
        return(false);
    }
Esempio n. 4
0
    public EdgeLoop(Vector2[] points, ILinkedGraphEdgeFactory <EdgeType> factory, Object[] factoryParams)
    {
        LinkedGraphVertex[] verts = new LinkedGraphVertex[points.Length];
        for (int i = 0; i < verts.Length; i++)
        {
            verts[i] = new LinkedGraphVertex(points[i]);
        }
        EdgeType[] newEdges = new EdgeType[points.Length];
        for (int i = 0; i < verts.Length; i++)
        {
            newEdges[i] = factory.GetEdge(verts[i], verts[(i + 1) % points.Length], factoryParams);//new EdgeLoopEdge(verts[i], verts[(i + 1) % points.Length]);
        }

        this.edges = new List <EdgeType>(newEdges);
        RecalculateBounds();

        if (!Verify())
        {
            Debug.LogWarning("Edge loop edges do not form a loop.");
        }

        foreach (EdgeType edge in edges)
        {
            edge.AddEdgeSplitListener(this);
        }
    }
Esempio n. 5
0
    public static EdgeType AddEdge(LinkedGraphVertex aVert, LinkedGraphVertex bVert, ILinkedGraphEdgeFactory <EdgeType> edgeFactory, System.Object[] factoryParams, List <EdgeType> knownEdges)
    {
        EdgeType newEdge = edgeFactory.GetEdge(aVert, bVert, factoryParams);

        if (knownEdges != null)
        {
            knownEdges.Add(newEdge);
        }

        return(newEdge);
    }
Esempio n. 6
0
    public LinkedGraphEdge(LinkedGraphVertex a, LinkedGraphVertex b)
    {
        this.a   = a;
        this.b   = b;
        segRef   = new Segment();
        segRef.a = a.pt;
        segRef.b = b.pt;

        a.AddConnection(this);
        b.AddConnection(this);

        listeners = new List <IEdgeSplitListener>();
    }
Esempio n. 7
0
    //given a list of edges, check if the vertex at pt already exists
    public static LinkedGraphVertex HasVertex(List <EdgeType> inEdges, Vector2 pt)
    {
        LinkedGraphVertex matchingVert = null;

        EnumerateVertices(inEdges, (LinkedGraphVertex vert) =>
        {
            if ((vert.pt - pt).sqrMagnitude < VERT_MERGE_DIST_SQR)
            {
                matchingVert = vert;
            }
        });
        return(matchingVert);
    }
Esempio n. 8
0
    public static void SubdivideEdge(EdgeType edge, LinkedGraphVertex midPoint, ILinkedGraphEdgeFactory <EdgeType> edgeFactory, List <EdgeType> knownEdges)
    {
        LinkedGraphVertex aVert = edge.a;
        LinkedGraphVertex bVert = edge.b;

        EdgeType aEdge = AddEdge(aVert, midPoint, edgeFactory, null, knownEdges);
        EdgeType bEdge = AddEdge(midPoint, bVert, edgeFactory, null, knownEdges);

        edge.OnEdgeSplit(aEdge, bEdge);

        knownEdges.Remove(edge);
        Detach(edge);
    }
Esempio n. 9
0
 public CityEdge GetEdge(LinkedGraphVertex a, LinkedGraphVertex b, System.Object[] data)
 {
     if (data == null)
     {
         return(new CityEdge(a, b, CityEdgeType.Unspecified, 1f));
     }
     else
     {
         if (data.Length >= 2 && data[0] is CityEdgeType && data[1] is float)
         {
             return(new CityEdge(a, b, (CityEdgeType)data[0], (float)data[1]));
         }
         Debug.LogWarning("Bad data for creating CityEdge");
         return(new CityEdge(a, b, CityEdgeType.Unspecified, 2f));
     }
 }
Esempio n. 10
0
 public LinkedGraphVertex GetOppositeVertex(LinkedGraphVertex vertex)
 {
     if (a != vertex && b != vertex)
     {
         Debug.LogWarning("Can't get opposite vertex.");
         return(null);
     }
     else
     {
         if (a == vertex)
         {
             return(b);
         }
         else
         {
             return(a);
         }
     }
 }
Esempio n. 11
0
    public void AddConnection(LinkedGraphEdge connection)
    {
        int insertIndex             = 0;
        LinkedGraphVertex otherVert = connection.GetOppositeVertex(this);
        float             newAngle  = HelperFunctions.AngleBetween(otherVert.pt - pt, Vector2.right) % (Mathf.PI * 2);

        for (int i = 0; i < connections.Count; i++)
        {
            LinkedGraphVertex thisOppositeVert = connections[i].GetOppositeVertex(this);
            float             existingAngle    = HelperFunctions.AngleBetween(thisOppositeVert.pt - pt, Vector2.right) % (Mathf.PI * 2);

            if (newAngle < existingAngle)
            {
                insertIndex++;
            }
            else
            {
                break;
            }
        }

        connections.Insert(insertIndex, connection);
    }
Esempio n. 12
0
    //given a list of edges that may intersect with the new edge, connect the new edge
    public static void ConnectNewEdge(Vector2 a, Vector2 b, ILinkedGraphEdgeFactory <EdgeType> edgeFactory, System.Object[] factoryParams, List <EdgeType> knownEdges)
    {
        LinkedGraphVertex aVert = HasVertex(knownEdges, a);
        LinkedGraphVertex bVert = HasVertex(knownEdges, b);

        if (aVert != null && bVert != null && aVert == bVert || (a - b).sqrMagnitude < VERT_MERGE_DIST_SQR)
        {
            return;
        }

        if (aVert == null)
        {
            aVert = new LinkedGraphVertex(a);
        }
        if (bVert == null)
        {
            bVert = new LinkedGraphVertex(b);
        }

        if (knownEdges == null || knownEdges.Count == 0)
        {
            AddEdge(aVert, bVert, edgeFactory, factoryParams, knownEdges);
            return;
        }

        //use for checking intersections
        Segment testingSegment   = Segment.SegmentWithPoints(a, b);
        Rect    testingSegBounds = testingSegment.ExpandedBounds(VERT_MERGE_DIST_SQR);

        List <LinkedGraphVertex> intersectionVertices = new List <LinkedGraphVertex>();

        intersectionVertices.Add(aVert);//these will be sorted later
        intersectionVertices.Add(bVert);

        EdgeType[] edgesCopy = new EdgeType[knownEdges.Count];
        knownEdges.CopyTo(edgesCopy);

        //check if new vertices are on another line
        foreach (EdgeType seg in edgesCopy)
        {
            if (!seg.segRef.bounds.Overlaps(testingSegBounds))
            {
                continue;
            }
            if (seg.a == aVert || seg.a == bVert || seg.b == aVert || seg.b == bVert)
            {
                //do nothing in this case.
                //this is captured in the base case of finding existing verts
            }
            else if (seg.segRef.ContainsPoint(a, VERT_MERGE_DIST_SQR))
            {
                SubdivideEdge(seg, aVert, edgeFactory, knownEdges);
            }
            else if (seg.segRef.ContainsPoint(b, VERT_MERGE_DIST_SQR))
            {
                SubdivideEdge(seg, bVert, edgeFactory, knownEdges);
            }
            else if (testingSegment.ContainsPoint(seg.a.pt, VERT_MERGE_DIST_SQR))
            {
                intersectionVertices.Add(seg.a);
            }
            else if (testingSegment.ContainsPoint(seg.b.pt, VERT_MERGE_DIST_SQR))
            {
                intersectionVertices.Add(seg.b);
            }
            else
            {
                Vector2 intersectionPoint = Vector2.zero;
                if (seg.segRef.IntersectionWithSegment(testingSegment, out intersectionPoint))
                {
                    LinkedGraphVertex midPtVert = new LinkedGraphVertex(intersectionPoint);
                    SubdivideEdge(seg, midPtVert, edgeFactory, knownEdges);
                    intersectionVertices.Add(midPtVert);
                }
            }
        }
        Vector2 sortDirection = b - a;

        intersectionVertices.Sort((first, second) =>
                                  (first.pt - a).sqrMagnitude.CompareTo(
                                      (second.pt - a).sqrMagnitude));

        for (int i = 0; i < intersectionVertices.Count - 1; i++)
        {
            AddEdge(intersectionVertices[i], intersectionVertices[i + 1], edgeFactory, factoryParams, knownEdges);
        }
    }
Esempio n. 13
0
 public static EdgeType AddEdge(LinkedGraphVertex aVert, LinkedGraphVertex bVert, ILinkedGraphEdgeFactory <EdgeType> edgeFactory, List <EdgeType> knownEdges)
 {
     return(AddEdge(aVert, bVert, edgeFactory, null, knownEdges));
 }
Esempio n. 14
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);
    }
Esempio n. 15
0
 public CityEdge(LinkedGraphVertex a, LinkedGraphVertex b, CityEdgeType type, float width) : base(a, b)
 {
     this.type  = type;
     this.id    = getID();
     this.width = width;
 }
Esempio n. 16
0
 public EdgeLoopEdge(LinkedGraphVertex a, LinkedGraphVertex b) : base(a, b)
 {
 }
Esempio n. 17
0
 public EdgeLoopEdge GetEdge(LinkedGraphVertex a, LinkedGraphVertex b, System.Object[] data)
 {
     return(new EdgeLoopEdge(a, b));
 }