神秘 "rnorm" 地形生成功能 javascript - 这是在做什么?

mystery "rnorm" function terrain generation javascript - what is this doing?

问题:这段代码到底在做什么?

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

上下文:我正在查看 Martin O'Leary 的 "Fantasy Map Generation" 代码 - full source here, which in short summary generates fantasy maps on the canvas. There is some insightful explanations of how the higher level process works 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];
    });
}

如果我还需要提供任何其他信息,请告诉我。这是我在这里的第一个问题,所以我可能对惯例有点软弱。

我认为这是可怕的代码。它似乎创建了一对值,z1z2,但不是将它们放在元组中并返回它 returns z1on每秒调用 相应的 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];
}

现代编译器应该能够避免为返回的文字和随后的解构分配数组。如果不是,您可以通过在 randomVector 中内联 rnorm 手动完成,尤其是 如果这是唯一调用它的地方。