问题描述
我正在尝试从 JS
重写代码到 Java
。代码是Diamond square算法。
来源是:
你可以玩 r
randomnes初始值和调整值以更改行为。你也可以改变初始的拐角值。
小心我的程序中的本地 int xs,ys
变量持有2值的功率不是2 +1的功率!!!
I am trying rewrite code from JS
to Java
. The code is Diamond square algorithm.
Source is: http://www.playfuljs.com/realistic-terrain-in-130-lines/
I rewrite code, but my code not working...
Output is bad.
My code in Java
is:
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.");
}
}
}
}
Can anyone help me?
Output of algo is int[][]
which i visualise using another program to image..
Visualise of output:
And this is how it should look
I am not getting error, but the output is wrong.Thanks for help.
I was coding this same thing yesterday (from the same source) and the recursive approach is really tricky due to square step overlaps of the subdivided areas and the irregularities in the same step. So I decided to do this from scratch the iterative way (which is much faster due to no heap/stack trashing in my programing environment) as you can see I am down from 130 lines to around 50 with comments.
This is how I do it (non recursively) in 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
}
I use my own picture
class so here some members:
resize(xs,ys)
resize image to new resolutionp[ys][xs].dd
is pixel access in form of 32 unsigned intsDWORD
pf
is pixel format (you can ignore this)
This is the result for diamond_square(513);
You can play with the r
randomnes initial and adjustment values to change behavior. Also you can change the initial corner values.
Beware the local int xs,ys
variables in my program holds the power of 2 values not the power of 2 +1 !!!
这篇关于菱形算法不起作用(从JS到JAVA重写代码)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!