稲妻を生成するアルゴリズムはありますか?
ボルトが着陸する場所を指定するセグメントまたはポイントオブジェクトのリストを生成するアルゴリズムが必要です。このメソッドには、開始点パラメーターとエンドポイントが必要です。ボルトにはランダムな分岐があり、ランダムな間隔でジグザグになっている必要があります。結果は、このように見えるランダムな稲妻効果になります
(ソース:wikimedia.org)
誰かがこれがうまくいくかもしれないアルゴリズムを知っているなら、助けは大歓迎です!
稲妻を生成するアルゴリズムはありますか?
ボルトが着陸する場所を指定するセグメントまたはポイントオブジェクトのリストを生成するアルゴリズムが必要です。このメソッドには、開始点パラメーターとエンドポイントが必要です。ボルトにはランダムな分岐があり、ランダムな間隔でジグザグになっている必要があります。結果は、このように見えるランダムな稲妻効果になります
(ソース:wikimedia.org)
誰かがこれがうまくいくかもしれないアルゴリズムを知っているなら、助けは大歓迎です!
回答:
ライティングボルトの生成に使用できるかなり簡単なアルゴリズムがあります。
ボルトの原点(O
)と終点(E
)の間の線分で開始します
その線上の点(ほぼまたは正確に真ん中)を選択して呼び出しS
、セグメントを2つの線セグメント(O->S
およびS->E
)に分割します。変位S
いくつかの小さなランダム量だけ(セグメントの法線に沿って)元の線分から離れます。これにより、単一の「曲がり」の稲妻が得られます。
ベンドを計算した後、小さなランダムチャンスに基づいて、3番目のラインセグメント(通常はO->S
セグメントの延長)を追加します。これが、雷の中で「フォーク」を生成する方法です。通常、この生成プロセス中にボルトの強度に関する情報を追跡する必要があります。これは、フォークをより暗くするか、より微妙なぼかしを持たせるためです。
次に、すべての新しい線分セグメントについて上記のプロセスを繰り返します。好みの形状を生成する繰り返し量を選択する必要があります。
このテクニックについては、私の友人のブログにかなり明確な説明があります(写真を恥知らずに盗んだ場所です)。グローエフェクトの追加についてもさらに詳しく説明します。
最後に、同じ基本アルゴリズムを説明するこのNVIDIAの論文もあります(これも詳細です)。
私は別のアプローチをお勧めします:迅速に探索するランダムツリー(RRT)です。それについての1つのクールなことは、あなたがそれを角を回って行くか、すべての方向に爆発させることができるということです。
アルゴリズムは本当に基本的なものです。
// Returns a random tree containing the start and the goal.
// Grows the tree for a maximum number of iterations.
Tree RRT(Node start, Node goal, int maxIters)
{
// Initialize a tree with a root as the start node.
Tree t = new Tree();
t.Root = start;
bool reachedGoal = false;
int iter = 0;
// Keep growing the tree until it contains the goal and we've
// grown for the required number of iterations.
while (!reachedGoal || iter < maxIters)
{
// Get a random node somewhere near the goal
Node random = RandomSample(goal);
// Get the closest node in the tree to the sample.
Node closest = t.GetClosestNode(random);
// Create a new node between the closest node and the sample.
Node extension = ExtendToward(closest, random);
// If we managed to create a new node, add it to the tree.
if (extension)
{
closest.AddChild(extension);
// If we haven't yet reached the goal, and the new node
// is very near the goal, add the goal to the tree.
if(!reachedGoal && extension.IsNear(goal))
{
extension.AddChild(goal);
reachedGoal = true;
}
}
iter++;
}
return t;
}
関数RandomSample
とExtendToward
関数を変更することにより、非常に異なるツリーを取得できます。RandomSample
どこでも均一にサンプリングする場合、ツリーはすべての方向に均一に成長します。目標に向かって偏っていると、ツリーは目標に向かって成長する傾向があります。常に目標をサンプリングする場合、ツリーは開始から目標まで直線になります。
ExtendToward
ツリーに対しても興味深いことを行うことができます。まず、障害物(壁など)がある場合、壁と衝突する拡張機能を拒否するだけで、障害物の周りにツリーを成長させることができます。
これは、サンプリングを目標に偏らせない場合の外観です。
(ソース:uiuc.edu)
そして、これは壁でどのように見えるかです
RRTのいくつかのクールなプロパティは、終了したら: