【问题标题】:Recursive method stopping prematurely on certain branches递归方法在某些分支上过早停止
【发布时间】:2014-05-18 18:27:24
【问题描述】:

我有以下递归方法在高度图中创建一座山:

private void createMountain(final float[][] heightMapping, final float startHeight) {
    boolean[][] traversed = new boolean[width][depth];
    boolean positive = (startHeight >= 0f);
    int x = random.nextInt(width);
    int z = random.nextInt(depth);
    recursiveUpdate(heightMapping, traversed, x, z, startHeight, positive);
}

private void recursiveUpdate(final float[][] heightMapping, final boolean[][] traversed, final int x, final int z, final float startHeight, final boolean positive) {
    if (x < 0 || x >= width || z < 0 || z >= depth) {
        return;
    }
    if (traversed[x][z]) {
        return;
    }
    if ((positive && startHeight <= 0f) || (!positive && startHeight >= 0f)) {
        heightMapping[x][z] = 0f;
        return;
    }
    traversed[x][z] = true;
    heightMapping[x][z] = startHeight;
    recursiveUpdate(heightMapping, traversed, x - 1, z - 1, calculateNewStartHeight(startHeight, positive), positive);
    recursiveUpdate(heightMapping, traversed, x - 1, z + 1, calculateNewStartHeight(startHeight, positive), positive);
    recursiveUpdate(heightMapping, traversed, x + 1, z - 1, calculateNewStartHeight(startHeight, positive), positive);
    recursiveUpdate(heightMapping, traversed, x + 1, z + 1, calculateNewStartHeight(startHeight, positive), positive);
}

private float calculateNewStartHeight(final float startHeight, final boolean positive) {
    float delta = random.nextFloat() * maxHeight / maxDecayFactor;
    return (positive) ? startHeight - delta : startHeight + delta;
}

这个想法是它从(x, z) 开始,然后递归地降低周围单元格的值(左下/右下/左上/右上),但是它似乎跳过了单元格,如图所示通过以下输出:

0.0  0.5  0.0  0.5  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
0.5  0.0  0.9  0.0  0.3  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
0.0  1.1  0.0  0.0  0.0  0.3  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
1.8  0.0  0.9  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
0.0  2.4  0.0  0.8  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
3.6  0.0  0.8  0.0  0.9  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
0.0  4.4  0.0  1.2  0.0  0.7  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
3.5  0.0  2.3  0.0  0.7  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
0.0  2.5  0.0  1.1  0.0  0.6  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
1.4  0.0  0.4  0.0  0.4  0.0  0.1  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
0.0  0.2  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  

在左侧,略高于中间的位置,您可以看到4.4,而且问题本身似乎很明显,它没有为上/下/左/右元素设置任何值,但我认为我的递归已经抓住了那个问题。

有什么线索吗?

【问题讨论】:

  • 你试过调试了吗?
  • @KubaSpatny 是的,代码中没有“错误”,这是我的算法中的一些设计缺陷,我没有掌握。
  • 输出应该是什么?您在输出上方的解释看起来像是在输出它应该是什么。
  • @mdewitt 我正在使用这个高度图在 3D 程序中投影地形。现在,山上有洞(以0.0 4.4 0.0 1.2 为例,它在0.0 都有洞,而我希望首先有一些低于4.4 的值,其次是在4.41.2 之间的一些值。
  • 对,但你说你只想做环绕左下、右下、左上、右上。所以你真的想要所有周围,包括左、左下、左上、上、右上、右和右下?

标签: java recursion


【解决方案1】:

您没有计算顶部、底部、左侧和右侧的递归高度。你只是在计算角落。您只需要添加“非角落”,即。 (x, y) 的顶部、底部、左侧和右侧索引到您的递归方法。

private void recursiveUpdate(final float[][] heightMapping, final boolean[][] traversed,
    final int x, final int z, final float startHeight, final boolean positive) {
    if (x < 0 || x >= width || z < 0 || z >= depth) {
        return;
    }
    if (traversed[x][z]) {
        return;
    }
    if ((positive && startHeight <= 0f) || (!positive && startHeight >= 0f)) {
        heightMapping[x][z] = 0f;
        return;
    }

    traversed[x][z] = true;
    heightMapping[x][z] = startHeight;
    //This will only calculate the corners of the (x,y point)
    recursiveUpdate(heightMapping, traversed, x - 1, z - 1, 
                    calculateNewStartHeight(startHeight, positive), positive);
    recursiveUpdate(heightMapping, traversed, x - 1, z + 1, 
                    calculateNewStartHeight(startHeight, positive), positive);
    recursiveUpdate(heightMapping, traversed, x + 1, z - 1, 
                    calculateNewStartHeight(startHeight, positive), positive);
    recursiveUpdate(heightMapping, traversed, x + 1, z + 1, 
                    calculateNewStartHeight(startHeight, positive), positive);

    //Add top, bottom, left and right indicies for (x,y)
    //bottom
    recursiveUpdate(heightMapping, traversed, x, z - 1, 
                    calculateNewStartHeight(startHeight, positive), positive);
    //top
    recursiveUpdate(heightMapping, traversed, x, z + 1, 
                    calculateNewStartHeight(startHeight, positive), positive);
    //right
    recursiveUpdate(heightMapping, traversed, x + 1, z, 
                    calculateNewStartHeight(startHeight, positive), positive);
    //left
    recursiveUpdate(heightMapping, traversed, x - 1, z, 
                    calculateNewStartHeight(startHeight, positive), positive);
}

【讨论】:

  • 谢谢,这确实解决了它。甚至设法通过在上/下/左/右上递归来稍微“优化”它,这实际上是我最初的想法。
猜你喜欢
  • 1970-01-01
  • 2020-09-16
  • 1970-01-01
  • 2012-01-25
  • 1970-01-01
  • 2011-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多