神秘的“rnorm”函数地形生成javascript - 这是做什么的?

时间:2017-11-22 20:32:31

标签: javascript vector terrain procedural-generation

问题:这段代码在世界上有什么作用?

另外:'w'的使用方式是某种现有的算法吗?我试图弄清楚函数的意图,或者至少描述它产生的数字类型。

背景:我正在看Martin O'Leary的“幻想地图生成”代码 - full source here,简短摘要会在画布上生成幻想地图。对于更高级别的流程如何工作有一些深刻的解释in a blog post,但这个级别太低,无法覆盖那里。有一个叫做'rnorm'的特殊功能可以在几个地方使用,我迷失了它的工作原理。我已将它包含在下面,然后是几个实例,它出现在某些上下文中。对这件事做的任何帮助都会很棒!

var rnorm = (function() {
    var z2 = null;

    function rnorm() {
        if (z2 != null) {
            var tmp = z2;
            z2 = null;
            return tmp;
        }
        var x1 = 0;
        var x2 = 0;
        var w = 2.0;
        while (w >= 1) {
            x1 = runif(-1, 1);
            x2 = runif(-1, 1);
            w = x1 * x1 + x2 * x2;
        }
        w = Math.sqrt(-2 * Math.log(w) / w);
        z2 = x2 * w;
        return x1 * w;
    }
    return rnorm;
})();
在上面的代码中调用的

runif()是一个短函数,它在两个给定值之间生成一个随机数

function runif(lo, hi) {
    return lo + Math.random() * (hi - lo);
}

此代码用于生成随机向量(实际上是生成过程中唯一使用的位置) -

function randomVector(scale) {
return [scale * rnorm(), scale * rnorm()];
}

但我认为它的作用不止于此,因为以下内容,当提供'randomVector(4)'的方向时,会在整个网格高度图上产生渐变斜率:编辑:不,它实际上是对渐变斜率没有影响。这是因为一些偷偷摸摸的事实,地图的一边是0,0,地图的另一边是宽度,高度,这会产生逐渐增加的数字。

function slope(mesh, direction) {
    return mesh.map(function (x) {
        return x[0] * direction[0] + x[1] * direction[1];
    });
}

如果我还有其他什么要提供,请告诉我。这是我在这里提出的第一个问题,所以我对惯例可能有点软。

1 个答案:

答案 0 :(得分:2)

我认为这是一个可怕的代码。它似乎创建了一对值z1z2,但不是将它们放在元组中并返回它,而是在每次第二次调用时返回z1 相应的z2值。我不知道为什么他们会做这样的事情,我唯一的猜测是避免分配对象并使语法使用更方便。

应该简化为

function rnorm() {
    var x1 = 0;
    var x2 = 0;
    var w = 2.0;
    while (w >= 1) {
        x1 = runif(-1, 1);
        x2 = runif(-1, 1);
        w = x1 * x1 + x2 * x2;
    }
    w = Math.sqrt(-2 * Math.log(w) / w);
    return [x1 * w, x2 * w];
}

function randomVector(scale) {
    var [z1, z2] = rnorm();
    return [scale * z1, scale * z2];
}

现代编译器应该能够避免返回的文字和随后的解构的数组分配。如果不是,您可以通过在rnorm特别是中内联randomVector来手动执行此操作,如果这是唯一一个被调用的地方。