我正在尝试从JS
重写代码到Java
。代码是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 < 0 || x > this.max || y < 0 || 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[][]
,我使用另一个程序来显示图像..
可视化输出:
这就是它的外观
我没有收到错误,但输出错误。 谢谢你的帮助。
答案 0 :(得分:0)
我昨天编写了同样的东西(来自同一个来源),由于细分区域的方形步长重叠和同一步骤中的不规则性,递归方法非常棘手。因此,我决定从头开始以迭代的方式执行此操作(由于我的编程环境中没有堆/堆栈,所以速度更快),因为您可以看到我从130行到50左右的评论。
这是我在 C ++ 中执行此操作(非递归):
void diamond_square(int size)
{
picture pic;
int x,y,xx,yy,xs,ys,d,d2,r;
for (xs=1;xs<size;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位无符号整数DWORD
pf
是像素格式(您可以忽略它)这是diamond_square(513);
您可以使用r
randomnes初始值和调整值来改变行为。您也可以更改初始角点值。
请注意我程序中的本地int xs,ys
变量保持2值的功率而不是2 +1的功率!!!