我从"Midpoint displacement algorithm example"获取代码,将其清理干净,并将其重新用作一维线性地形生成器。以下是doMidpoint()
方法的新版本:
public boolean setMidpointDisplacement(int x1, int x2) {
// Exit recursion if points are next to eachother
if (x2 - x1 < 2) {
return false;
}
final int midX = (x1 + x2) / 2;
final int dist = x2 - x1;
final int distHalf = dist / 2;
final int y1 = map[x1];
final int y2 = map[x2];
final int delta = random.nextInt(dist) - distHalf; // +/- half the distance
final int sum = y1 + y2;
map[midX] = (sum + delta) / 2; // Sets the midpoint
// Divide and repeat
setMidpointDisplacement(x1, midX);
setMidpointDisplacement(midX, x2);
return true;
}
代码似乎运行良好并产生可行的地形(你可以看到how I've tested it,带有基本的GUI)
阅读"Generating Random Fractal Terrain"和"Mid Point Displacement Algorithm"后,我的问题是:
如何识别此代码隐式使用的“粗糙度常量”?然后,我该如何改变呢?
此外,这可能与我的主要问题直接相关,也可能没有,但我注意到代码将y值的总和加到“delta”(变化量)并将其除以2 - - 尽管这与求和的平均值相同,然后加上delta / 2。这与“粗糙度常数”有关吗?我在想我能做到
map[midX] = sum/2 + delta/K;
和K现在代表'粗糙度常数',但我不确定这是否准确,因为它似乎允许我控制平滑但不直接控制“随机数是多少每次通过“生成随机分形地形”定义的循环减少范围。
就像我之前说过的那样,我将我发现的2D MDP噪声发生器移植到一维版本中 - 但我相当确定我做到了准确,所以这不是任何问题的根源。
答案 0 :(得分:1)
如何识别粗糙度常数&#39;这段代码隐含地使用了什么?
在cited中,粗糙度是减少最大随机位移的量。当你的位移是random.nextInt(dist) = dist*random.nextDouble()
时,你的dist = x2-x1
和你从一个递归步骤走到另一个递归步骤,其中一半是这个dist,它跟随roughness == 1
(在引用的术语中)
然后,我该如何改变呢?
public boolean setMidpointDisplacement(int x1, int x2, int roughness) {
// Exit recursion if points are next to eachother
if (x2 - x1 < 2) {
return false;
}
// this is 2^-roughness as per cited
// you can pass it precalculated as a param, using it as such here
// is only to put it into a relation with the cited
double factor=1.0/(1<<roughness);
final int midX = (x1 + x2) / 2;
final int dist = x2 - x1;
final int distHalf = dist / 2;
final int y1 = map[x1];
final int y2 = map[x2];
// and you apply it here. A cast will be necessary though
final int delta = factor*(random.nextInt(dist) - distHalf); // +/- half the distance
final int sum = y1 + y2;
map[midX] = (sum + delta) / 2; // Sets the midpoint
// Divide and repeat
setMidpointDisplacement(x1, midX, roughness);
setMidpointDisplacement(midX, x2, roughness);
return true;
}
此外,这可能与我的主要问题直接相关,也可能没有,但我注意到代码将y值的总和加到了&#34; delta&#34; (改变金额)并将其除以2
他们的方式具有通过单一划分来实现它的优势。在处理int
时,累积的截断误差会因单个div而变小(更不用说稍快一点)。