Пример #1
0
        /// <summary>
        /// Superimposes ONE hole group's ledge groups.
        /// There isn't much else to say, so check out that disgusting number of input parameters.
        /// Hopefully nobody on earth ever looks at this except me.
        /// </summary>
        /// <param name="ledgeCollMap"></param>
        /// <param name="ledgeGroupMap"></param>
        /// <param name="baseTileMap"></param>
        /// <param name="superTileMap"></param>
        /// <param name="preTileMap"></param>
        /// <param name="tileGroup"></param>
        /// <param name="holeGroup"></param>
        /// <returns></returns>
        private static (Dictionary <LedgeCollKey, EdgeCollection <TileEdge> >, Dictionary <LedgeGroupKey, int>) _SuperimposeHoleGroup(
            IDictionary <LedgeCollKey, EdgeCollection <TileEdge> > ledgeCollMap,
            IDictionary <LedgeGroupKey, int> ledgeGroupMap,
            TileMap baseTileMap,
            TileMap superTileMap,
            TileMap preTileMap,
            int tileGroup,
            int holeGroup)
        {
            var ledgeCollMapClone  = new Dictionary <LedgeCollKey, EdgeCollection <TileEdge> >(ledgeCollMap);
            var ledgeGroupMapClone = new Dictionary <LedgeGroupKey, int>(ledgeGroupMap);

            int superLedgeGroup = 0; //Once superimposed, # of ledge groups CAN change
            int maxLedgeGroups  = ledgeGroupMap[new LedgeGroupKey(baseTileMap, tileGroup, holeGroup, preTileMap)];

            for (int ledgeGroup = 0; ledgeGroup < maxLedgeGroups; ledgeGroup++)
            {
                EdgeCollection <TileEdge> ledgeColl   = ledgeCollMap[new LedgeCollKey(baseTileMap, tileGroup, holeGroup, preTileMap, ledgeGroup)];
                EdgeCollection <TileEdge> validLedges = _BuildHoleGroupValidLedges(ledgeColl, preTileMap, superTileMap);

                while (validLedges.Count > 0)
                { //repeatedly GetOrderedGroup() on valid_ledges until no ledges are left behind
                    EdgeCollection <TileEdge> orderedLedges = validLedges.GetOrderedCollection();
                    var validSet = new HashSet <TileEdge>(validLedges);
                    validSet.ExceptWith(orderedLedges);
                    validLedges = new EdgeCollection <TileEdge>(validSet);
                    ledgeCollMapClone.Add(new LedgeCollKey(baseTileMap, tileGroup, holeGroup, superTileMap, superLedgeGroup), orderedLedges);
                    superLedgeGroup++;
                }
            }
            ledgeGroupMapClone.Add(new LedgeGroupKey(baseTileMap, tileGroup, holeGroup, superTileMap), superLedgeGroup);
            return(ledgeCollMapClone, ledgeGroupMapClone);
        }
Пример #2
0
        /// <summary>
        /// Given a single perimeter, separate it into different ledge groups as appropriate, separate its Edges
        /// into different EdgeCollections, one for each ledge group, then return both as dictionaries.
        /// </summary>
        /// <param name="ledgeCollMap">Dict which maps ledge group to EdgeCollection.</param>
        /// <param name="ledgeGroupMap">Dict which maps superimposed TileMap to ledge group.</param>
        /// The above two are here for copy-and-return purposes (maintaining object immutability).
        /// <param name="tileMaps">List of all TileMaps.</param>
        /// <param name="tileMap">TileMap that ledges are being filled for.</param>
        ///<param name="perimeter">EdgeCollection holding perimeter which will be separated in this func.</param>
        /// <param name="tileGroup">TileGroup that ledges are being filled for.</param>
        /// <param name="holeGroup">HoleGroup that ledges are being filled for.</param>
        /// <returns>Two dictionaries matching the two input dicts but with the new ledge data added to each.</returns>
        private static (Dictionary <LedgeCollKey, EdgeCollection <TileEdge> >, Dictionary <LedgeGroupKey, int>) _FillLedges(
            IDictionary <LedgeCollKey, EdgeCollection <TileEdge> > ledgeCollMap,
            IDictionary <LedgeGroupKey, int> ledgeGroupMap,
            TileMapList tileMaps,
            TileMap tileMap,
            EdgeCollection <TileEdge> perimeter,
            int tileGroup,
            int holeGroup)
        {
            var ledgeCollMapClone  = new Dictionary <LedgeCollKey, EdgeCollection <TileEdge> >(ledgeCollMap);
            var ledgeGroupMapClone = new Dictionary <LedgeGroupKey, int>(ledgeGroupMap);

            var ledges     = new EdgeCollection <TileEdge>();
            int ledgeGroup = 0;

            foreach (TileEdge edge in perimeter)
            {
                Vector2 currentTile  = edge.tileCoords;
                int     currentLayer = tileMap.ZIndex;
                Vector2 adjTile      = _GetAdjacentLowerTile(tileMaps, edge, currentLayer);

                if (adjTile == currentTile)
                { //no adjacent tile exists
                    ledges.Add(edge);
                }
                else if (ledges.Count > 0)
                { //gap in ledges, finish current ledge group and move to next one
                    ledgeCollMapClone.Add(new LedgeCollKey(tileMap, tileGroup, holeGroup, tileMap, ledgeGroup),
                                          new EdgeCollection <TileEdge>(ledges.GetOrderedCollection()));
                    ledgeGroup++;
                    ledges = new EdgeCollection <TileEdge>();
                }
            }

            if (ledges.Count > 0)
            { //store ledges if not done already
                ledgeCollMapClone.Add(new LedgeCollKey(tileMap, tileGroup, holeGroup, tileMap, ledgeGroup),
                                      new EdgeCollection <TileEdge>(ledges.GetOrderedCollection()));
                ledgeGroup++;
            }

            ledgeGroupMapClone.Add(new LedgeGroupKey(tileMap, tileGroup, holeGroup, tileMap), ledgeGroup);
            return(ledgeCollMapClone, ledgeGroupMapClone);
        }
        /// <summary>
        /// Attempts to get a collection of edges in CCW order that is a small cycle.  Uses PolygonSplittingGraphNode to
        /// extract small cycles.
        /// </summary>
        /// <param name="edgeColl"></param>
        /// <returns>CCW collection of edges that forms a small loop(s).</returns>
        public static List <EdgeCollection <TileEdge> > GetSmallClosedLoops(this EdgeCollection <TileEdge> edgeColl)
        {
            if (edgeColl is null)
            {
                throw new ArgumentNullException(nameof(edgeColl));
            }

            EdgeCollection <TileEdge>                   connectedColl = edgeColl.GetOrderedCollection();
            Dictionary <PolyEdge, TileEdge>             polyToTileMap = _InitTilePolyBiDict(connectedColl);
            SortedList <int, PolygonSplittingGraphNode> polygonNodes  = _CreatePolygonGraphSplittingNodes(polyToTileMap);
            var graph = new PolygonSplittingGraph(polygonNodes.Values.ToList());
            List <ChordlessPolygon> smallLoops = graph.GetMinCycles();

            var allTileEdgeLoops = new List <EdgeCollection <TileEdge> >();

            foreach (ChordlessPolygon poly in smallLoops)
            {
                List <TileEdge> smallLoopsEdges = _ConvertChordlessPolygonToPolyEdges(poly.outerPerimUnsimplified, polyToTileMap);
                allTileEdgeLoops.Add(new EdgeCollection <TileEdge>(smallLoopsEdges));
            }
            return(allTileEdgeLoops);
        }