3

1000x600pxのキャンバスがあります。キャンバスの外にスプライトをスポーンしたい(ただし、均等に分散されている)。(-500、-500)と(1500、1100)の間でランダムな値を取得するが、(0、0)と(1000、600)の間では取得しないための最良の方法は何ですか?whileループを使用して、範囲内になるまで数値を生成できることは理解していますが、それは不要のようです。ありがとう。

4

4 に答える 4

4

0 から 1000 を除いて -500 から 1500 の間の数値を生成したい場合は、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);

2 次元の点については、より創造的になる必要があります。まず、禁止領域内にある 2 つのポイントを生成し、それらの値を適切な領域に広げます。

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

500を超える場合は、0から1000までの乱数を生成します。それを否定しない場合は、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 に答える