我从"Midpoint displacement algorithm example"中获取了代码,对其进行了一些清理,并重新将其作为1D线性地形生成器工作下面是我的新版本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噪声发生器移植到了1d版本中——但我相当肯定我做得很准确,所以这不是任何问题的根源。

最佳答案

如何识别此代码隐式使用的“粗糙度常数”?
cited中,粗糙度是减小最大随机位移的量当你的位移是random.nextInt(dist) = dist*random.nextDouble(),你的dist = x2-x1并且你用这个距离的一半从一个递归步骤转到另一个递归步骤时,它遵循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值的和添加到“delta”(更改量)中,并将其除以2
他们的方法有一个优势,就是只用一个部门。当您使用ints时,使用单个div时,累积的截断错误将更小(更不用说稍快一点)。

关于algorithm - 此中点位移算法的“粗糙度常数”是什么,如何修改?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41032840/

10-10 22:52