ここでは、完全な矩形に一般化することができます1つの象限のためにそれを行う方法です:
第一象限(赤+オレンジ+グリーン)での総画素数を計算する:
int totalPixels = w * h;
を
int invalidCornerPixels = (int)((float)(r * r) * ((4.0f - PI)/4.0f));
オレンジエリア:
そして赤色領域(丸みを帯びた四角形の外側にある隅のピクセル)を計算します赤い領域に等しい。赤+緑領域のピクセルをサンプリングし、赤領域にある場合は、代わりにオレンジ領域のランダムピクセルをサンプリングします。
int pixelIndex = randomValue(redGreenArea);
int pixelX = pixelIndex % w;
int pixelY = pixelIndex/w;
テストサンプリング画素は赤色領域であり、必要に応じてリサンプリングする場合:
if((pixelX < r) && (pixelY < r))
{
int circleX = r - pixelX;
int circleY = r - pixelY;
if(((circleX * circleX) + (circleY * circleY)) > (r * r))
{
pixelIndex = randomValue(invalidCornerPixels) + redGreenArea;
pixelX = pixelIndex % w;
pixelY = pixelIndex/w;
}
}
この1 -
int redGreenArea = totalPixels - invalidCornerPixels;
はrandomValue(n)
が0からnまでのランダムな整数を返すと仮定する最大2つの乱数生成(通常は1つだけ)が必要で、拒否サンプリングよりも複雑ではありません。同じテストを実装する必要があるためです。 totalPixels
,invalidCornerPixels
およびredGreenArea
の計算は、1回行うことができ、所定の矩形に対して保存することができます。
弱点は、丸め誤差のため、実際にテストに失敗するピクセル数が正確にはinvalidCornerPixels
に等しくないことがあり、非常にわずかに不均一な分布になることです。あなたは、ブルートフォースオフライン(r x rの正方形でテストに失敗したピクセルを数える)とrの各値のルックアップテーブルを作成してinvalidCornerPixels
を計算することで対処することができます。しかし、パーティクルジェネレータに使用すると目立つことはないだろう。別の弱点は、赤い領域がオレンジ色の領域に重なっていると失敗することです。
関連する寸法を定量化できますか?どのくらいの長方形ですか?分析的に表現することができる四半期の円か何かの形で四捨五入されていますか?いくつかの実際のパラメータ値を与えることができますか? – pjs
[拒否サンプリング](https://en.wikipedia.org/wiki/Rejection_sampling)を使用する簡単でわかりやすい方法にこだわってみませんか?あなたの丸い矩形の凸包のためのちょうどxとyをサンプリングします(=丸められていないrect)。サンプリングされた点がrect内にあれば受け入れます。 (あなたの不合格領域は全領域に比べて小さくすべきです) – sascha
rectはスクリーンのサイズに見合っています。コーナー半径は5〜175ピクセルです。拒否サンプリングの方法は、そのパフォーマンスの欠点のために受け入れられません。私の場合は重要です(モバイルゲームではパーティクルシステムのエミッター) – Papirosnik