Esempio n. 1
0
        internal override TileModelMapping GetTileModelMapping(ITopology topology)
        {
            var gridTopology = topology.AsGridTopology();
            var patternModel = new PatternModel
            {
                Propagator  = propagator.Select(x => x.Select(y => y.ToArray()).ToArray()).ToArray(),
                Frequencies = frequencies.ToArray(),
            };

            GridTopology patternTopology;
            Dictionary <int, IReadOnlyDictionary <Tile, ISet <int> > > tilesToPatternsByOffset;
            Dictionary <int, IReadOnlyDictionary <int, Tile> >         patternsToTilesByOffset;
            ITopoArray <(Point, int, int)>         tileCoordToPatternCoordIndexAndOffset;
            ITopoArray <List <(Point, int, int)> > patternCoordToTileCoordIndexAndOffset;

            if (!(gridTopology.PeriodicX && gridTopology.PeriodicY && gridTopology.PeriodicZ))
            {
                // Shrink the topology as patterns can cover multiple tiles.
                patternTopology = gridTopology.WithSize(
                    gridTopology.PeriodicX ? topology.Width : topology.Width - NX + 1,
                    gridTopology.PeriodicY ? topology.Height : topology.Height - NY + 1,
                    gridTopology.PeriodicZ ? topology.Depth : topology.Depth - NZ + 1);


                void OverlapCoord(int x, int width, out int px, out int ox)
                {
                    if (x < width)
                    {
                        px = x;
                        ox = 0;
                    }
                    else
                    {
                        px = width - 1;
                        ox = x - px;
                    }
                }

                int CombineOffsets(int ox, int oy, int oz)
                {
                    return(ox + oy * NX + oz * NX * NY);
                }

                (Point, int, int) Map(Point t)
                {
                    OverlapCoord(t.X, patternTopology.Width, out var px, out var ox);
                    OverlapCoord(t.Y, patternTopology.Height, out var py, out var oy);
                    OverlapCoord(t.Z, patternTopology.Depth, out var pz, out var oz);
                    var patternIndex = patternTopology.GetIndex(px, py, pz);

                    return(new Point(px, py, pz), patternIndex, CombineOffsets(ox, oy, oz));
                }

                /*
                 * (Point, int, int) RMap(Point t)
                 * {
                 *  OverlapCoord(t.X, patternTopology.Width, out var px, out var ox);
                 *  OverlapCoord(t.Y, patternTopology.Height, out var py, out var oy);
                 *  OverlapCoord(t.Z, patternTopology.Depth, out var pz, out var oz);
                 *  var patternIndex = patternTopology.GetIndex(px, py, pz);
                 *  return (new Point(px, py, pz), patternIndex, CombineOffsets(ox, oy, oz));
                 * }
                 */

                tileCoordToPatternCoordIndexAndOffset = TopoArray.CreateByPoint(Map, gridTopology);
                var patternCoordToTileCoordIndexAndOffsetValues = new List <(Point, int, int)> [patternTopology.Width, patternTopology.Height, patternTopology.Depth];