예제 #1
0
    protected List <EdgeType[]> CollectChildLoops(SubdividableEdgeLoop <EdgeType> parent, List <DividingEdge> dividingEdges)
    {
        List <EdgeType> knownEdges    = new List <EdgeType>(parent.GetEdgesEnumerable());
        Polygon         parentPoly    = parent.GetPolygon();
        Path            polygonAsClip = parentPoly.ClipperPath(HelperFunctions.clipperScale);

        Vector2[] parentPoints = parent.GetPoints();

        //kinda ugly, these two variables are implicitly paired together
        Paths edgePaths = new Paths();
        List <ILinkedGraphEdgeFactory <EdgeType> > edgePathFactories = new List <ILinkedGraphEdgeFactory <EdgeType> >();
        List <System.Object[]> edgePathFactoriesParams = new List <System.Object[]>();

        foreach (DividingEdge edge in dividingEdges)
        {
            Path edgePath = new Path();
            edgePath.Add(HelperFunctions.GetIntPoint(edge.p1));
            edgePath.Add(HelperFunctions.GetIntPoint(edge.p2));

            PolyTree clippedResults = new PolyTree();
            Clipper  clipper        = new Clipper();

            clipper.AddPath(edgePath, PolyType.ptSubject, false);
            clipper.AddPath(polygonAsClip, PolyType.ptClip, true);
            clipper.Execute(ClipType.ctIntersection, clippedResults);

            Paths subPaths = Clipper.OpenPathsFromPolyTree(clippedResults);
            edgePaths.AddRange(subPaths);
            //if this edge was split into multiple paths when intersecting with parent poly, note that each subpath has the same factory
            foreach (Path path in subPaths)
            {
                edgePathFactories.Add(edge.factory);
                edgePathFactoriesParams.Add(edge.factoryParams);
            }
        }

        DebugLines debug = GameObject.FindObjectOfType <DebugLines>();


        int totalAddedEdges = 0;

        for (int j = 0; j < edgePaths.Count; j++)
        {
            Path edgePath = edgePaths[j];
            ILinkedGraphEdgeFactory <EdgeType> edgeFactory = edgePathFactories[j];
            System.Object[] edgeParams = edgePathFactoriesParams[j];
            //this is almost always just 2 elements in which case it runs once
            for (int i = 0; i < edgePath.Count - 1; i++)
            {
                //convert path back into regular coordinates. Watch out that there is high enough resolution
                //that when this conversion happens, the linkedGraph still thinks points/edges are adjacent and connects them
                Vector2 p1 = HelperFunctions.GetPoint(edgePath[i]);
                Vector2 p2 = HelperFunctions.GetPoint(edgePath[i + 1]);

                LinkedGraph <EdgeType> .ConnectNewEdge(p1, p2, edgeFactory, edgeParams, knownEdges);

                totalAddedEdges++;
            }
        }

        List <EdgeType[]> formedChildLoops = parent.GetInteriorEdgeLoops();

        if (formedChildLoops.Count == 0)
        {
            Debug.Log("No Children " + parent.GetHashCode());
        }
        return(formedChildLoops);
    }
예제 #2
0
    public override List <SubdividableEdgeLoop <CityEdge> > GetChildren(SubdividableEdgeLoop <CityEdge> parent)
    {
        Polygon parentPoly = parent.GetPolygon();

        Path polygonAsClip = parentPoly.ClipperPath(HelperFunctions.clipperScale);


        CityEdge[] edges = parent.GetEdges();

        //------------------------------------------ OLD BAD STUFF
        //Paths edgePaths = new Paths();

        //Paths expandedLine = new Paths();

        //float width = 2f;
        //ClipperOffset clipperOffset = new ClipperOffset();
        //clipperOffset.AddPath(polygonAsClip, JoinType.jtSquare, EndType.etClosedPolygon);
        //clipperOffset.Execute(ref expandedLine, HelperFunctions.clipperScale * (-width / 2));

        //if (expandedLine.Count > 0)
        //{
        //    Path shrunkPoly = expandedLine[0];
        //    LinkedGraphVertex[] subPlotVerts = new LinkedGraphVertex[shrunkPoly.Count];
        //    for (int i = 0; i < shrunkPoly.Count; i++)
        //    {
        //        subPlotVerts[i] = new LinkedGraphVertex(HelperFunctions.GetPoint(shrunkPoly[i]));
        //    }
        //    CityEdge[] subPlotEdges = new CityEdge[shrunkPoly.Count];
        //    for (int i = 0; i < shrunkPoly.Count; i++)
        //    {
        //        subPlotEdges[i] = new CityEdge(subPlotVerts[i], subPlotVerts[(i + 1) % shrunkPoly.Count], CityEdgeType.PlotBoundary, 0f);
        //    }

        //    SubdividableEdgeLoop<CityEdge> plot = parent.GetNextChild(subPlotEdges);
        //    Polygon plotPoly = parent.GetPolygon();


        //    return new List<SubdividableEdgeLoop<CityEdge>> { plot };
        //}

        //return new List<SubdividableEdgeLoop<CityEdge>>();


        //--------------------------------------------------------------------------- OLD BAD STUFF END


        bool shapeRemains = true;

        //int uniqueEdgeStartEdge = -1;
        //for (int i = 0; i < edges.Length; i ++)
        //{
        //    if (!edges[(i+1)%edges.Length].GetID().Equals(edges[i].GetID()))
        //    {
        //        uniqueEdgeStartEdge = (i + 1) % edges.Length;
        //        break;
        //    }
        //}

        //LinkedGraphVertex anchorVert = edges[uniqueEdgeStartEdge].GetOppositeVertex(edges[uniqueEdgeStartEdge].GetSharedVertex(edges[(uniqueEdgeStartEdge+1)%edges.Length]));
        //LinkedGraphVertex previusVert = null;

        for (int j = 0; j < edges.Length; j++)
        {
            CityEdge edge = edges[j];

            //int nextIndex = (j + uniqueEdgeStartEdge + 1) % edges.Length;
            //LinkedGraphVertex thisVert = edge.GetOppositeVertex()

            Path edgeLine = new Path();
            edgeLine.Add(HelperFunctions.GetIntPoint(edge.a.pt));
            edgeLine.Add(HelperFunctions.GetIntPoint(edge.b.pt));

            Paths expandedLine = new Paths();

            float         width         = edge.GetWidth() * HelperFunctions.clipperScale;
            ClipperOffset clipperOffset = new ClipperOffset();
            clipperOffset.AddPath(edgeLine, JoinType.jtMiter, EndType.etOpenSquare);
            clipperOffset.Execute(ref expandedLine, width / 2);

            //since we only expand a single line, we should only have one path left

            Paths   differenceSolution = new Paths();
            Clipper clipper            = new Clipper();
            clipper.AddPath(polygonAsClip, PolyType.ptSubject, true);
            clipper.AddPath(expandedLine[0], PolyType.ptClip, true);
            clipper.Execute(ClipType.ctDifference, differenceSolution);
            //Debug.Log("diff sol count: " + differenceSolution.Count);
            if (differenceSolution.Count == 0)
            {
                shapeRemains = false;
                break;
            }
            else
            {
                Path  maxAreaPath = null;
                float maxArea     = 0f;

                foreach (Path path in differenceSolution)
                {
                    Vector2[] points = new Vector2[path.Count];
                    int       i      = 0;
                    foreach (IntPoint p in path)
                    {
                        points[i] = HelperFunctions.GetPoint(p);
                        i++;
                    }
                    Polygon testPoly = new Polygon(points);
                    if (testPoly.area > maxArea)
                    {
                        maxArea     = testPoly.area;
                        maxAreaPath = path;
                    }
                }
                polygonAsClip = maxAreaPath;

                if (maxAreaPath == null)
                {
                    shapeRemains = false;
                    break;
                }
            }
        }
        if (shapeRemains)
        {
            for (int i = polygonAsClip.Count - 1; i >= 0; i--)
            {
                for (int j = 0; j < i; j++)
                {
                    if (polygonAsClip[i].X == polygonAsClip[j].X && polygonAsClip[i].Y == polygonAsClip[j].Y)
                    {
                        polygonAsClip.RemoveAt(i);
                        Debug.Log("removed dup of interior plot");
                    }
                }
            }
        }

        Vector2[] parentPoints = parent.GetPoints();
        ILinkedGraphEdgeFactory <CityEdge> factory = new CityEdgeFactory();

        System.Object[] roadCapBoundarySettings = new System.Object[] { CityEdgeType.EdgeCap, 0f };
        System.Object[] plotBoundarySettings    = new System.Object[] { CityEdgeType.PlotBoundary, 0f };

        if (shapeRemains && polygonAsClip.Count > 0)
        {
            List <DividingEdge> dividingEdges = new List <DividingEdge>();
            Vector2[]           subPlotVerts  = new Vector2[polygonAsClip.Count];
            for (int i = 0; i < polygonAsClip.Count; i++)
            {
                subPlotVerts[i] = HelperFunctions.GetPoint(polygonAsClip[i]);
            }

            List <CityEdge> knownEdges = new List <CityEdge>(parent.GetEdgesEnumerable());


            for (int i = 0; i < parentPoints.Length; i++)
            {
                float closestVertDistance = float.MaxValue;
                int   closestVertIndex    = -1;
                for (int j = 0; j < subPlotVerts.Length; j++)
                {
                    float thisDist = (parentPoints[i] - subPlotVerts[j]).sqrMagnitude;
                    if (thisDist < closestVertDistance)
                    {
                        closestVertDistance = thisDist;
                        closestVertIndex    = j;
                    }
                }
                dividingEdges.Add(new DividingEdge(parentPoints[i], subPlotVerts[closestVertIndex], factory, roadCapBoundarySettings));
            }

            for (int i = 0; i < subPlotVerts.Length; i++)
            {
                dividingEdges.Add(new DividingEdge(subPlotVerts[i], subPlotVerts[(i + 1) % subPlotVerts.Length], factory, plotBoundarySettings));
            }

            List <CityEdge[]> formedChildRegions = CollectChildLoops(parent, dividingEdges);

            List <SubdividableEdgeLoop <CityEdge> > children = new List <SubdividableEdgeLoop <CityEdge> >();

            for (int i = 0; i < formedChildRegions.Count; i++)
            {
                CityEdge[] loop = formedChildRegions[i];
                bool       allPlotBoundaries = true;
                for (int j = 0; j < loop.Length; j++)
                {
                    if (loop[j].GetRoadType() != CityEdgeType.PlotBoundary)
                    {
                        allPlotBoundaries = false;
                    }
                }
                if (allPlotBoundaries)
                {
                    children.Add(parent.GetNextChild(loop));
                }
                else
                {
                    children.Add(new Road(loop, city));
                }
            }

            return(children);
            //return new List<SubdividableEdgeLoop<CityEdge>>();
        }


        return(new List <SubdividableEdgeLoop <CityEdge> >());
    }