public void GenerateOverlappingOutput()
        {
            inputOverlappingData = dataProvider.GetInputOverlappingData();
            var modelParams = new OverlappingModelParams(width, height, depth, patternSize);

            modelParams.PeriodicInput  = periodicInput;
            modelParams.PeriodicOutput = periodicOutput;
            modelParams.Symmetry       = symmetry;
            modelParams.Ground         = foundation;

            overlappingModel = new OvelappingModel2dWrapper(inputOverlappingData, modelParams);
            renderer.Init(overlappingModel);

            runningCoroutine = StartCoroutine(overlappingModel.Model.RunViaEnumerator(0, iterations, OnResult, OnIteration));
        }
Beispiel #2
0
        public override InputOverlappingData GetInputOverlappingData()
        {
            if (Application.isPlaying == false)
            {
                FillPrefabMap();
            }

            var tileConfigData = CreateTileConfigData(tilePrefab => new TileConfig(tilePrefab));

            var inputData = new InputOverlappingData(tileConfigData, width, depth);

            ExecuteForEachTile((tile, pos, rotation) =>
            {
                inputData.SetTile(tileConfigData.GetConfig(tile.name), (int)pos.x, (int)pos.z, rotation);
            });

            return(inputData);
        }
Beispiel #3
0
        public OverlappingModel(InputOverlappingData inputData, OverlappingModelParams modelParams)
            : base(modelParams)
        {
            InputData = inputData;
            N         = modelParams.PatternSize;

            bool periodicInput = modelParams.PeriodicInput;
            int  symmetry      = modelParams.Symmetry;
            int  ground        = modelParams.Ground;

            periodic = modelParams.PeriodicOutput;

            int SMX = inputData.Width, SMY = inputData.Depth;

            var sample = inputData.GetSampleMatrix();

            int  C = inputData.TilesSortedByIds.Count;
            long W = ModelHelper.Power(C, N * N);

            Func <Func <int, int, byte>, byte[]> pattern = (f) =>
            {
                byte[] result = new byte[N * N];
                for (int y = 0; y < N; y++)
                {
                    for (int x = 0; x < N; x++)
                    {
                        result[x + y * N] = f(x, y);
                    }
                }

                return(result);
            };

            Func <int, int, byte[]> patternFromSample = (x, y) =>
            {
                return(pattern((dx, dy) => sample[(x + dx) % SMX, (y + dy) % SMY]));
            };
            Func <byte[], byte[]> rotate = (p) =>
            {
                return(pattern((x, y) => p[N - 1 - y + x * N]));
            };
            Func <byte[], byte[]> reflect = (p) =>
            {
                return(pattern((x, y) => p[N - 1 - x + y * N]));
            };

            Func <byte[], long> GenerateUniqueIndex = p =>
            {
                long result = 0, power = 1;
                for (int i = 0; i < p.Length; i++)
                {
                    result += p[p.Length - 1 - i] * power;
                    power  *= C;
                }

                return(result);
            };

            Func <long, byte[]> patternFromIndex = ind =>
            {
                long   residue = ind, power = W;
                byte[] result = new byte[N * N];

                for (int i = 0; i < result.Length; i++)
                {
                    power /= C;
                    int count = 0;

                    while (residue >= power)
                    {
                        residue -= power;
                        count++;
                    }

                    result[i] = (byte)count;
                }

                return(result);
            };

            Dictionary <long, int> weights  = new Dictionary <long, int>();
            List <long>            ordering = new List <long>();

            for (int y = 0; y < (periodicInput ? SMY : SMY - N + 1); y++)
            {
                for (int x = 0; x < (periodicInput ? SMX : SMX - N + 1); x++)
                {
                    byte[][] ps = new byte[8][];

                    ps[0] = patternFromSample(x, y);
                    ps[1] = reflect(ps[0]);
                    ps[2] = rotate(ps[0]);
                    ps[3] = reflect(ps[2]);
                    ps[4] = rotate(ps[2]);
                    ps[5] = reflect(ps[4]);
                    ps[6] = rotate(ps[4]);
                    ps[7] = reflect(ps[6]);

                    for (int k = 0; k < symmetry; k++)
                    {
                        long ind = GenerateUniqueIndex(ps[k]);
                        if (weights.ContainsKey(ind))
                        {
                            weights[ind]++;
                        }
                        else
                        {
                            weights.Add(ind, 1);
                            ordering.Add(ind);
                        }
                    }
                }
            }

            T           = weights.Count;
            this.ground = (ground + T) % T;

            patterns   = new byte[T][];
            stationary = new double[T];
            propagator = new int[2 * N - 1][][][];

            int counter = 0;

            foreach (long w in ordering)
            {
                patterns[counter]   = patternFromIndex(w);
                stationary[counter] = weights[w];
                counter++;
            }

            InitWave();

            Func <byte[], byte[], int, int, bool> agrees = (p1, p2, dx, dy) =>
            {
                int xmin = dx < 0 ? 0 : dx, xmax = dx < 0 ? dx + N : N, ymin = dy < 0 ? 0 : dy, ymax = dy < 0 ? dy + N : N;
                for (int y = ymin; y < ymax; y++)
                {
                    for (int x = xmin; x < xmax; x++)
                    {
                        if (p1[x + N * y] != p2[x - dx + N * (y - dy)])
                        {
                            return(false);
                        }
                    }
                }
                return(true);
            };

            for (int x = 0; x < 2 * N - 1; x++)
            {
                propagator[x] = new int[2 * N - 1][][];
                for (int y = 0; y < 2 * N - 1; y++)
                {
                    propagator[x][y] = new int[T][];
                    for (int t = 0; t < T; t++)
                    {
                        List <int> list = new List <int>();
                        for (int t2 = 0; t2 < T; t2++)
                        {
                            if (agrees(patterns[t], patterns[t2], x - N + 1, y - N + 1))
                            {
                                list.Add(t2);
                            }
                        }

                        propagator[x][y][t] = new int[list.Count];
                        for (int c = 0; c < list.Count; c++)
                        {
                            propagator[x][y][t][c] = list[c];
                        }
                    }
                }
            }
        }
 public OvelappingModel2dWrapper(InputOverlappingData inputData, OverlappingModelParams modelParam)
 {
     ModelParam = modelParam;
     Model      = new OverlappingModel2d(inputData, modelParam);
 }