Як можна створити ефект блискавки?


26

Чи існує алгоритм для створення блискавки?

Мені б хотілося, щоб алгоритм генерував список сегментних або точкових об'єктів із зазначенням місця, куди приземлиться болт. Методу знадобиться параметр початкової точки разом із кінцевою точкою. Болт повинен мати випадкові гілки, що відходять від нього, і зигзаг з випадковими інтервалами. В результаті вийде випадковий ефект блискавки, який виглядав би приблизно так


(джерело: wikimedia.org )

Якщо хтось знає про алгоритм, для якого це може працювати, допомога буде дуже вдячна!


2
Цей документ від Nvidia повинен бути саме тим, що вам потрібно, хоча він може бути занадто обширним. Перевірте слайди 7 на 11, вони мають гарні малюнки, які мають дати вам уявлення, на що слід прагнути. Якщо ви перейдете за другим посиланням, ви знайдете вихідний код (C ++, Direct3D). developer.download.nvidia.com/SDK/10/direct3d/Source/Lightning/… developer.download.nvidia.com/SDK/10/direct3d/samples.html
Помилка

Відповіді:


32

Існує досить простий алгоритм, який можна використовувати для створення освітлювальних болтів.

Почніть з відрізка лінії між початком болта ( O) і кінцевою точкою ( E)

Виберіть точку на цій лінії (приблизно або точно посередині), назвіть Sі розділіть сегмент на два відрізки рядка ( O->Sі S->E). Змістіть Sвід сегмента вихідної лінії (уздовж відрізка нормалі) деякої малої випадкової сумою. Це дає вам єдиний «вигин» блискавки.

Після обчислення вигину, виходячи з невеликого випадкового шансу, вам потрібно буде додати сегмент третього рядка (зазвичай це розширення O->Sсегмента). Ось так ви виробляєте «вилки» у блискавці. Зазвичай ви хочете відслідковувати інформацію про інтенсивність болта під час цього процесу генерації, тому що ви хочете, щоб вилки були тьмянішими або мали більш тонке розмиття:

введіть тут опис зображення

Потім повторіть описаний вище процес для всіх нових сегментів рядка; вам потрібно вибрати суму повторення, яка створює форми, які вам подобаються:

введіть тут опис зображення

Тут є досить чітке пояснення цієї техніки в блозі мого друга (саме там я безсоромно вкрав фотографії); це додає додаткової глибини щодо додання ефекту світіння.

Нарешті, є також цей документ NVIDIA, який описує той самий базовий алгоритм (також з більш детальною інформацією).


13

Я рекомендував би альтернативний підхід: швидко досліджуване випадкове дерево (RRT) . Хороша річ у тому, що ви можете змусити її ходити по кутах або вибухати в усі сторони.

Алгоритм дійсно основний:

// 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може дозволити вам робити цікаві речі і для дерева. По-перше, якщо у вас є перешкоди (наприклад, стіни), ви можете змусити дерево рости навколо них, просто відкинувши розширення, що стикаються зі стінами.

Ось як це виглядає, коли ви не зміщуєте вибірку до мети:

img
(джерело: uiuc.edu )

А ось як це виглядає зі стінами

Деякі цікаві властивості RRT після його закінчення:

  • RRT ніколи не перетне себе
  • Зрештою, RRT покриє весь простір все меншими та меншими гілками
  • Шлях від початку до мети може бути абсолютно випадковим і дивним.

Я просто використовував цей алгоритм для створення анімації блискавки. Треба сказати, що це спрацювало дуже добре! У коді є основні помилки, такі як iter не збільшується в кожному циклі. Окрім цього, це майже готово використовувати як розміщено
applejacks01
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.