Как создать эффект удара молнии?

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 в конечном итоге покроет все пространство все меньшими и меньшими ветвями
  • Путь от начала до цели может быть совершенно случайным и странным.
mklingen
источник
Я просто использовал этот алгоритм для генерации анимации молнии. Я должен сказать, что это сработало очень хорошо! В коде есть большая опечатка, такая как iter не увеличивается каждый цикл. Кроме этого это почти готово использовать как отправлено
applejacks01