3

我有一个 1000x600 像素的画布。我想在画布外生成精灵(但分布均匀)。检索 (-500, -500) 和 (1500, 1100) 之间但不在 (0, 0) 和 (1000, 600) 之间的随机值的最佳方法是什么?我知道可以使用 while 循环来生成数字,直到它们在范围内,但这似乎是多余的。谢谢。

4

4 回答 4

4

如果你想生成一个介于 -500 和 1500 之间的数字,不包括 0 到 1000,你可以只生成一个介于 0 和 1000 之间的数字(0 - -500 + 1500 - 1000)。

如果数字小于 500,则减去 500;如果数字大于或等于 500,则加 500。

或者,更一般地说:

function randomInt(outerMin, outerMax, innerMin, innerMax)
{
    var usableRange = innerMin - outerMin + outerMax - innerMax,
    threshold = innerMin - outerMin,
    num = Math.floor(Math.random() * (usableRange + 1));

    if (num < threshold) {
        return num - threshold;
    } else {
        return num - threshold + innerMax;
    }
}

randomInt(-500, 1500, 0, 1000);

对于二维点,您必须更有创意。首先,您生成两个位于禁止区域内的点,然后将这些值传播到好的区域:

function randomVector(outer, inner)
{
    var innerWidth = inner.right - inner.left,
    innerHeight = inner.bottom - inner.top,
    x = Math.floor(Math.random() * (innerWidth + 1)),
    y = Math.floor(Math.random() * (innerHeight + 1)),
    midx = Math.floor(innerWidth / 2),
    midy = Math.floor(innerHeight / 2);

    if (x < midx) { // left side of forbidden area, spread left
        x = x / midx * (inner.left - outer.left) - inner.left;
    } else { // right side of forbidden area, spread right
        x = (x - midx) / midx * (outer.right - inner.right) + inner.right;
    }

    if (y < midy) { // top side of forbidden area, spread top
        y = y / midy * (inner.top - outer.top) - inner.top;
    } else { // bottom side of forbidden area, spread bottom
        y = (y - midy) / midy * (outer.bottom - inner.bottom) + inner.bottom;
    }

    // at this point I'm not sure how to round them
    // but it probably should have happened one step above :)
    return {
        x: Math.floor(x),
        y: Math.floor(y)
    }
}

randomVector({
    left: -500,
    top: -500,
    right: 1500,
    bottom: 1100
 }, {
    left: 0,
    top: 0,
    right: 1000,
    bottom: 600
 });

重要的

这是有效的,因为您的“禁止”区域之外的区域在它们各自的维度上是相等的,即padding-top == padding-bottom && padding-left == padding-right.

如果这将不同,则分布不再均匀。

于 2012-12-14T14:07:33.057 回答
2

生成一个介于 0 到 1000 之间的随机数,如果超过 500,则添加 500(或分别为 600),如果不否定它。

于 2012-12-14T14:09:27.257 回答
2

您可以计算一组允许的矩形,而不是一组禁止的矩形。要在任何允许的矩形内获得随机位置,您首先选择一个随机矩形,然后在该选定矩形内选择一个随机位置。

当矩形的大小不相等时,您需要按面积加权,否则较小的矩形将比较大的矩形具有更高的密度(200x100 矩形需要是 10x20 矩形的 100 倍)。

于 2012-12-14T14:16:17.950 回答
0

只需生成 (0,0) 和 (1,1) 之间的那些数字,然后使用一些线性函数进行映射。

否则,将您希望随机坐标落入矩形的区域划分为矩形。假设您获得了 N 个这样的矩形。这些矩形中的每一个都可以通过将 (0,0) 和 (1,1) 之间的随机生成器的输出映射到该矩形来填充(这是一个线性映射)。

于 2012-12-14T14:07:28.587 回答