稲妻効果を生成するにはどうすればよいですか?


26

稲妻を生成するアルゴリズムはありますか?

ボルトが着陸する場所を指定するセグメントまたはポイントオブジェクトのリストを生成するアルゴリズムが必要です。このメソッドには、開始点パラメーターとエンドポイントが必要です。ボルトにはランダムな分岐があり、ランダムな間隔でジグザグになっている必要があります。結果は、このように見えるランダムな稲妻効果になります


(ソース:wikimedia.org

誰かがこれがうまくいくかもしれないアルゴリズムを知っているなら、助けは大歓迎です!


2
Nvidiaによるこの論文は、あなたが必要とするものだけであるべきですが、少し広範すぎるかもしれません。スライド7から11を確認してください。これらには、何を狙うべきかを理解できる素敵な印象があります。2番目のリンクをたどると、ソースコード(C ++、Direct3D)が見つかります。developer.download.nvidia.com/SDK/10/direct3d/Source/Lightning/... developer.download.nvidia.com/SDK/10/direct3d/samples.html
障害

回答:


32

ライティングボルトの生成に使用できるかなり簡単なアルゴリズムがあります。

ボルトの原点(O)と終点(E)の間の線分で開始します

その線上の点(ほぼまたは正確に真ん中)を選択して呼び出しS、セグメントを2つの線セグメント(O->SおよびS->E)に分割します。変位Sいくつかの小さなランダム量だけ(セグメントの法線に沿って)元の線分から離れます。これにより、単一の「曲がり」の稲妻が得られます。

ベンドを計算した後、小さなランダムチャンスに基づいて、3番目のラインセグメント(通常はO->Sセグメントの延長)を追加します。これが、雷の中で「フォーク」を生成する方法です。通常、この生成プロセス中にボルトの強度に関する情報を追跡する必要があります。これは、フォークをより暗くするか、より微妙なぼかしを持たせるためです。

ここに画像の説明を入力してください

次に、すべての新しい線分セグメントについて上記のプロセスを繰り返します。好みの形状を生成する繰り返し量を選択する必要があります。

ここに画像の説明を入力してください

このテクニックについては、私の友人のブログにかなり明確な説明があります(写真を恥知らずに盗んだ場所です)。グローエフェクトの追加についてもさらに詳しく説明します。

最後に、同じ基本アルゴリズムを説明するこのNVIDIAの論文もあります(これも詳細です)。


13

私は別のアプローチをお勧めします:迅速に探索するランダムツリー(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;
}

関数RandomSampleExtendToward関数を変更することにより、非常に異なるツリーを取得できます。RandomSampleどこでも均一にサンプリングする場合、ツリーはすべての方向に均一に成長します。目標に向かって偏っていると、ツリーは目標に向かって成長する傾向があります。常に目標をサンプリングする場合、ツリーは開始から目標まで直線になります。

ExtendTowardツリーに対しても興味深いことを行うことができます。まず、障害物(壁など)がある場合、壁と衝突する拡張機能を拒否するだけで、障害物の周りにツリーを成長させることができます。

これは、サンプリングを目標に偏らせない場合の外観です。

img
(ソース:uiuc.edu

そして、これは壁でどのように見えるかです

RRTのいくつかのクールなプロパティは、終了したら:

  • RRTは決して交差しません
  • RRTは、最終的にはますます小さなブランチでスペース全体をカバーします
  • スタートからゴールまでの道のりは、完全にランダムで奇妙なものです。

このアルゴリズムを使用して、稲妻のアニメーションを生成しました。私はそれが本当にうまくいったと言わなければなりません!コードには、ループごとにインクリメントされないiterなどの大きなタイプミスがあります。それ以外は、これは投稿されたようにほとんど使用する準備ができています
-applejacks01
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.