菱形算法不起作用(从JS到JAVA重写代码)

我正在尝试从JSJava重写代码。 代码是Diamond square算法。

来源是: http : //www.playfuljs.com/realistic-terrain-in-130-lines/

我重写代码,但我的代码不工作……

输出很糟糕。

我在Java中的代码是:

 public class MapGenerator { public static void main(String[] args) { MapGenerator mg = new MapGenerator(9); mg.generate(); mg.printMap(); } private int size, max; double[] map; int[][] matrix; public MapGenerator(int detail) { this.size = (int) Math.pow(2, detail) + 1; this.max = this.size - 1; this.map = new double[this.size * this.size]; } private double get(int x, int y) { if (x  this.max || y  this.max) { return -1; } return this.map[x + this.size * y]; } private void set(int x, int y, double val) { this.map[x + this.size * y] = val; } public void generate() { set(0, 0, max); set(this.max, 0, max / 2); set(this.max, this.max, 0); set(0, this.max, max / 2); divide(this.max); buildMatrix(); saveTerrain(0, 0, 0, 0, matrix, "vystup.ter"); } private void buildMatrix() { matrix = new int[size][size]; for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < matrix[0].length; j++) { matrix[i][j] = (int) map[i + j]; } } } private void divide(int size) { //? double roughness = 0.7; int x, y, half = size / 2; double scale = roughness * size; if (half < 1) { return; } for (y = half; y < max; y += size) { for (x = half; x < max; x += size) { square(x, y, half, Library.randInt(0, 100) * scale * 2 - scale); } } for (y = 0; y <= max; y += half) { for (x = (y + half) % size; x <= max; x += size) { diamond(x, y, half, Library.randInt(0, 100) * scale * 2 - scale); } } divide(size / 2); } private void square(int x, int y, int size, double offset) { double tmp_1 = get(x, y - size); // top double tmp_2 = get(x + size, y); // right double tmp_3 = get(x, y + size); // bottom double tmp_4 = get(x - size, y); // left set(x, y, ((tmp_1 + tmp_2 + tmp_3 + tmp_4) / 4.0) + offset); } private void diamond(int x, int y, int size, double offset) { double tmp_1 = get(x, y - size); // top double tmp_2 = get(x + size, y); // right double tmp_3 = get(x, y + size); // bottom double tmp_4 = get(x - size, y); // left set(x, y, ((tmp_1 + tmp_2 + tmp_3 + tmp_4) / 4.0) + offset); } public void printMap() { for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < matrix[0].length; j++) { System.out.print(matrix[i][j] + " "); } System.out.println(""); } } public void saveTerrain(int canonX, int canonY, int targetX, int targetY, int[][] terrain, String fName) { int height = terrain.length; int width = terrain[0].length; DataOutputStream fout = null; try { // Samotný zápis dat fout = new DataOutputStream(new FileOutputStream(fName)); fout.writeInt(width); fout.writeInt(height); fout.writeInt(canonX); fout.writeInt(canonY); fout.writeInt(targetX); fout.writeInt(targetY); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { fout.writeInt(terrain[y][x]); } } } /* * Následuje pouze zavření souboru a ošetrení výjimek */ catch (FileNotFoundException e) { System.err.println("Nepovedlo se otevrit vystupni soubor."); } catch (IOException e) { System.err.println("Nepovedlo se zapsat vystupni soubor."); } finally { try { if (fout != null) { fout.close(); } } catch (IOException e) { System.err.println("Nepovedlo se uzavrit vystupni soubor."); } } } } 

谁能帮我?

algo的输出是int[][] ,我使用另一个程序来显示图像。

可视化输出:

输出图像链接

这就是它的外观

输出图像链接

我没有收到错误,但输出错误。 感谢帮助。

我昨天编写了同样的东西(来自同一个来源),由于细分区域的方形步长重叠和同一步骤中的不规则性,递归方法非常棘手。 因此我决定从头开始以迭代的方式执行此操作(由于我的编程环境中没有堆/堆栈,所以速度更快),因为您可以看到我从130行到50左右的评论。

这就是我在C ++中的表达方式 (非递归):

 void diamond_square(int size) { picture pic; int x,y,xx,yy,xs,ys,d,d2,r; for (xs=1;xs>=1; ys=xs; // align to power of 2 pic.resize(xs+1,ys+1); pic.pf=_pf_u; // resize image to power of 2 +1 d=xs; d2=d>>1; r=128; // init step,half step and randomness Randomize(); pic.p[ 0][ 0].dd=r; // set corners values (should be random but I want this) pic.p[ 0][xs].dd=r; pic.p[ys][ 0].dd=r; pic.p[ys][xs].dd=r; for (;d2;d=d2,d2>>=1) // subdivide step until full image is filled { // diamond for (y=d2,yy=ys-d2;y<=yy;y+=d) for (x=d2,xx=xs-d2;x<=xx;x+=d) pic.p[y][x].dd=((pic.p[y-d2][x-d2].dd+pic.p[y-d2][x+d2].dd+pic.p[y+d2][x-d2].dd+pic.p[y+d2][x+d2].dd)>>2)+Random(r); // square for (y=d2,yy=ys-d2;y<=yy;y+=d) for (x=d ,xx=xs-d ;x<=xx;x+=d) pic.p[y][x].dd=((pic.p[y][x-d2].dd+pic.p[y][x+d2].dd+pic.p[y-d2][x].dd+pic.p[y+d2][x].dd)>>2)+Random(r); for (y=d ,yy=ys-d ;y<=yy;y+=d) for (x=d2,xx=xs-d2;x<=xx;x+=d) pic.p[y][x].dd=((pic.p[y][x-d2].dd+pic.p[y][x+d2].dd+pic.p[y-d2][x].dd+pic.p[y+d2][x].dd)>>2)+Random(r); for (x=d2,xx=xs-d2;x<=xx;x+=d) { y= 0; pic.p[y][x].dd=((pic.p[y][x-d2].dd+pic.p[y][x+d2].dd+pic.p[y+d2][x].dd)/3)+Random(r); y=ys; pic.p[y][x].dd=((pic.p[y][x-d2].dd+pic.p[y][x+d2].dd+pic.p[y-d2][x].dd)/3)+Random(r); } for (y=d2,yy=ys-d2;y<=yy;y+=d) { x= 0; pic.p[y][x].dd=((pic.p[y][x+d2].dd+pic.p[y-d2][x].dd+pic.p[y+d2][x].dd)/3)+Random(r); x=xs; pic.p[y][x].dd=((pic.p[y][x-d2].dd+pic.p[y-d2][x].dd+pic.p[y+d2][x].dd)/3)+Random(r); } // adjust randomness r=(r*220)>>8; if (r<2) r=2; } // here pic holds the terrain map } 

我使用自己的picture类,所以这里有一些成员:

  • resize(xs,ys)图像调整为新分辨率
  • p[ys][xs].dd是32个无符号整数DWORDforms的像素访问
  • pf是像素格式(你可以忽略这个)

这是diamond_square(513);的结果diamond_square(513);

例

您可以使用r randomnes初始值和调整值来更改行为。 您也可以更改初始角点值。

注意我的程序中的本地int xs,ys变量保持2值的幂而不是2 +1的幂!