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)); }
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); }
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); }