private void Gen(int sizeX, int sizeY, int base_freq, float pers, long seed, int x_o, int y_o) { if (!Utils.isPowerOf2(sizeX)) throw new Exception("sizeX must be power of 2"); if (!Utils.isPowerOf2(sizeY)) throw new Exception("sizeY must be power of 2"); int iterationsX = Utils.powerOf2Log2(sizeX); int iterationsY = Utils.powerOf2Log2(sizeY); base_freq = Math.Max(base_freq, 0); base_freq = Math.Min(base_freq, iterationsX); random = new Random((int)seed); channel = new Channel(sizeX, sizeY); int x_block, y_block, x, y; if (base_freq > 0) { int block_size = sizeX>>base_freq; for (int x_b = 0; x_b < (1<<base_freq); x_b++) { for (int y_b = 0; y_b < (1<<base_freq); y_b++) { x = x_b*block_size; y = y_b*block_size; channel.putPixel(x, y, (float)random.NextDouble()); } } } float v1, v2, v3, v4, v5, v6, v7, v8, v9; for (int i = base_freq; i < iterationsX; i++) { int block_size = sizeX>>i; int block_size_half = sizeX>>(i + 1); float amp = (float)Math.Pow(pers, i - base_freq); float amp_half = 0.5f*amp; float avr; // calculate center midpoints if (i < 2) { for (x_block = 0, x = 0; x_block < (1<<i); x_block++) { for (y_block = 0, y = 0; y_block < (1<<i); y_block++) { v1 = channel.getPixel(x, y); v2 = channel.getPixel((x + block_size) % sizeX, y); v3 = channel.getPixel(x, (y + block_size) % sizeY); v4 = channel.getPixel((x + block_size) % sizeX, (y + block_size) % sizeY); avr = 0.25f*(v1 + v2 + v3 + v4); v5 = avr*(1f + (float)random.NextDouble()*amp - amp_half); channel.putPixel(x + block_size_half, y + block_size_half, v5); y+= block_size; } x+= block_size; } } else { // safe blocks for (x_block = 1, x = block_size; x_block < (1<<i) - 1; x_block++) { for (y_block = 1, y = block_size; y_block < (1<<i) - 1; y_block++) { v1 = channel.getPixel(x, y); v2 = channel.getPixel(x + block_size, y); v3 = channel.getPixel(x, y + block_size); v4 = channel.getPixel(x + block_size, y + block_size); avr = 0.25f*(v1 + v2 + v3 + v4); v5 = avr*(1f + (float)random.NextDouble()*amp - amp_half); channel.putPixel(x + block_size_half, y + block_size_half, v5); y+= block_size; } x+= block_size; } // left and right edge blocks for (x_block = 0; x_block < (1<<i); x_block+= (1<<i) - 1) { x = x_block*block_size; for (y_block = 0, y = 0; y_block < (1<<i); y_block++) { v1 = channel.getPixel(x, y); v2 = channel.getPixel((x + block_size) % sizeX, y); v3 = channel.getPixel(x, (y + block_size) % sizeY); v4 = channel.getPixel((x + block_size) % sizeX, (y + block_size) % sizeY); avr = 0.25f*(v1 + v2 + v3 + v4); v5 = avr*(1f + (float)random.NextDouble()*amp - amp_half); channel.putPixel(x + block_size_half, y + block_size_half, v5); y+= block_size; } } // top and bottom edge blocks for (x_block = 1, x = block_size; x_block < (1<<i) - 1; x_block++) { for (y_block = 0; y_block < (1<<i); y_block+= (1<<i) - 1) { y = y_block*block_size; v1 = channel.getPixel(x, y); v2 = channel.getPixel((x + block_size) % sizeX, y); v3 = channel.getPixel(x, (y + block_size) % sizeY); v4 = channel.getPixel((x + block_size) % sizeX, (y + block_size) % sizeY); avr = 0.25f*(v1 + v2 + v3 + v4); v5 = avr*(1f + (float)random.NextDouble()*amp - amp_half); channel.putPixel(x + block_size_half, y + block_size_half, v5); } x+= block_size; } } // calculate left and bottom edge midpoints if (i < 2) { for (x_block = 0, x = 0; x_block < (1<<i); x_block++) { for (y_block = 0, y = 0; y_block < (1<<i); y_block++) { v1 = channel.getPixel(x, y); v5 = channel.getPixel(x + block_size_half, y + block_size_half); v2 = channel.getPixel((x + block_size) % sizeX, y); v3 = channel.getPixel(x, (y + block_size) % sizeY); v6 = channel.getPixel(((x - block_size_half) + sizeX) % sizeX, (y + block_size_half) % sizeY); v7 = channel.getPixel((x + block_size_half) % sizeX, ((y - block_size_half) + sizeY) % sizeY); avr = 0.25f*(v1 + v3 + v5 + v6); v8 = avr*(1f + (float)random.NextDouble()*amp - amp_half); avr = 0.25f*(v1 + v2 + v5 + v7); v9 = avr*(1f + (float)random.NextDouble()*amp - amp_half); channel.putPixel(x, y + block_size_half, v8); channel.putPixel(x + block_size_half, y, v9); y+= block_size; } x+= block_size; } } else { // safe blocks for (x_block = 1, x = block_size; x_block < (1<<i) - 1; x_block++) { for (y_block = 1, y = block_size; y_block < (1<<i) - 1; y_block++) { v1 = channel.getPixel(x, y); v5 = channel.getPixel(x + block_size_half, y + block_size_half); v2 = channel.getPixel(x + block_size, y); v3 = channel.getPixel(x, y + block_size); v6 = channel.getPixel(x - block_size_half, y + block_size_half); v7 = channel.getPixel(x + block_size_half, y - block_size_half); avr = 0.25f*(v1 + v3 + v5 + v6); v8 = avr*(1f + (float)random.NextDouble()*amp - amp_half); avr = 0.25f*(v1 + v2 + v5 + v7); v9 = avr*(1f + (float)random.NextDouble()*amp - amp_half); channel.putPixel(x, y + block_size_half, v8); channel.putPixel(x + block_size_half, y, v9); y+= block_size; } x+= block_size; } // left and right edge blocks for (x_block = 0; x_block < (1<<i); x_block+= (1<<i) - 1) { x = x_block*block_size; for (y_block = 0, y = 0; y_block < (1<<i); y_block++) { v1 = channel.getPixel(x, y); v5 = channel.getPixel(x + block_size_half, y + block_size_half); v2 = channel.getPixel((x + block_size) % sizeX, y); v3 = channel.getPixel(x, (y + block_size) % sizeY); v6 = channel.getPixel(((x - block_size_half) + sizeX) % sizeX, (y + block_size_half) % sizeY); v7 = channel.getPixel((x + block_size_half) % sizeX, ((y - block_size_half) + sizeY) % sizeY); avr = 0.25f*(v1 + v3 + v5 + v6); v8 = avr*(1f + (float)random.NextDouble()*amp - amp_half); avr = 0.25f*(v1 + v2 + v5 + v7); v9 = avr*(1f + (float)random.NextDouble()*amp - amp_half); channel.putPixel(x, y + block_size_half, v8); channel.putPixel(x + block_size_half, y, v9); y+= block_size; } } // top and bottom edge blocks for (x_block = 1, x = block_size; x_block < (1<<i) - 1; x_block++) { for (y_block = 0; y_block < (1<<i); y_block+= (1<<i) - 1) { y = y_block*block_size; v1 = channel.getPixel(x, y); v5 = channel.getPixel(x + block_size_half, y + block_size_half); v2 = channel.getPixel((x + block_size) % sizeX, y); v3 = channel.getPixel(x, (y + block_size) % sizeY); v6 = channel.getPixel(((x - block_size_half) + sizeX) % sizeX, (y + block_size_half) % sizeY); v7 = channel.getPixel((x + block_size_half) % sizeX, ((y - block_size_half) + sizeY) % sizeY); avr = 0.25f*(v1 + v3 + v5 + v6); v8 = avr*(1f + (float)random.NextDouble()*amp - amp_half); avr = 0.25f*(v1 + v2 + v5 + v7); v9 = avr*(1f + (float)random.NextDouble()*amp - amp_half); channel.putPixel(x, y + block_size_half, v8); channel.putPixel(x + block_size_half, y, v9); } x+= block_size; } } } float[] mm=channel.findMinMax(); //Console.WriteLine("Range Mountain->[{0},{1}]",mm[0],mm[1]); channel.normalize(); mm=channel.findMinMax(); //Console.WriteLine("Range Mountain->[{0},{1}]",mm[0],mm[1]); }