March 1, 2022

Выражение: Seed Random

seedRandom() — это умный метод, который придумала Adobe, чтобы позволить нам контролировать степень случайности. На самом деле он имеет более чем одно применение. Вы также можете использовать его только для изменения последовательности случайных чисел, сгенерированных random(). seedRandom() имеет два параметра. Первый — это случайное начальное число, а второй — флаг true/false, который сообщает After Effects, будут ли случайные числа, сгенерированные random(), «вечными». Через минуту мы вернемся к этому «вечному» делу, но сначала давайте посмотрим на другой параметр. В своей простейшей форме seedRandom просто запускает генератор случайных чисел для создания определенной последовательности случайных чисел, которая будет меняться в каждом кадре.

Например, эти два выражения будут генерировать совершенно разные последовательности случайных чисел (которые будут меняться в каждом кадре):

seedRandom(3);
random()

seedRandom(999);
random()

ОК, а вот и самое интересное. Установив для второго параметра seedRandom() значение «true», числа, сгенерированные random(), будут одинаковыми для каждого кадра. Вот пример выражения для положения, которое перемещает слой в случайное положение и удерживает его в этом месте:

seedRandom(3,true);
random([thisComp.width,thisComp.height])

Помните, что без вызова seedRandom() слой будет перемещаться в разные позиции в каждом кадре. Как это нам поможет? Когда слой перемещается в случайное положение и остается там, довольно скучно, верно? Да это так. Но все, что нам нужно сделать, чтобы получить новую позицию, — это изменить семя. Таким образом, чтобы заставить слой перемещаться случайным образом упорядоченным образом, все, что нам нужно сделать, это периодически обновлять начальное значение и получать новую случайную позицию из random(). Давайте построим пример. Скажем, мы хотим, чтобы наш слой перемещался в новую случайную позицию каждые полсекунды. Все, что нам нужно, это какой-то новый код в нашем выражении, который будет менять начальное число каждые полсекунды. Как бы мы это сделали? Помните, что функция JavaScript Math.floor() округляет до ближайшего целого числа в меньшую сторону. Мы можем использовать это для генерации начального значения, которое меняется каждые полсекунды, путем деления текущего времени на 0,5 и округления до ближайшего целого числа. Вот пример (вы должны изменить значение «holdTime», чтобы изменить продолжительность удержания каждой позиции):

holdTime = .5; //time to hold each position (seconds)

seed = Math.floor(time/holdTime);
seedRandom(seed,true);
random([thisComp.width, thisComp.height])

Теперь слой по-прежнему перемещается хаотично, но с интервалом в полсекунды. Давайте внесем изменения, чтобы наше движение оставалось в «безопасной для заголовков» области композиции. Мы сделаем это, ограничив результаты вызовов random() значениями от 10% до 90% ширины и высоты композиции. Вот измененный код:

holdTime = .5; //time to hold each position (seconds)
minVal = [0.1*thisComp.width, 0.1*thisComp.height];
maxVal = [0.9*thisComp.width, 0.9*thisComp.height];

seed = Math.floor(time/holdTime);
seedRandom(seed,true);
random(minVal,maxVal)

Хорошо, так лучше, но что, если мы хотим, чтобы слой плавно перемещался из одного положения в другое? Это подводит нас к одной из наиболее важных концепций генерации случайного движения, а именно к тому, что всякий раз, когда вы устанавливаете начальное число в определенное число, случайная последовательность, сгенерированная random(), всегда будет одной и той же. Например, если мы установим начальное число равным 1, random() может дать нам 0,45633. Если мы изменим начальное число на 2, мы можем получить 0,78341. Но если мы изменим начальное число обратно на 1, мы снова получим 0,45633. Так как же это помогает нам генерировать плавное случайное движение? Давайте снова посмотрим на наш пример выше. Для первой половины секунды начальное значение равно 0. Таким образом, для каждого кадра в первой половине секунды вызов random() генерирует одну и ту же случайную позицию на основе начального значения 0. После первой половины секунды начальное значение изменяется на 1, а случайная позиция изменяется. Так что, если бы мы «заглянули вперед», изменив начальное значение на значение, которое мы будем использовать в следующие полсекунды, чтобы увидеть, какой будет следующая позиция, и начать двигаться туда?

Последовательность будет заключаться в том, чтобы вычислить начальное значение для этой половины секунды, использовать его для получения случайной позиции для этой половины секунды (которая будет нашей начальной позицией), увеличить начальное значение на единицу и использовать это, чтобы увидеть, какова случайная начальная позиция для следующая половина секунды будет (которую мы будем использовать в качестве конечной позиции для текущего полусекундного сегмента). Хорошо, вот код:

segDur = .5;// duration of each "segment" of random motion
minVal = [0.1*thisComp.width, 0.1*thisComp.height];
maxVal = [0.9*thisComp.width, 0.9*thisComp.height];

seed = Math.floor(time/segDur);
segStart = seed*segDur;
seedRandom(seed,true);
startVal =  random(minVal,maxVal);
seedRandom(seed+1,true);
endVal = random(minVal,maxVal);
ease(time,segStart,segStart + segDur, startVal, endVal);

Вы заметите, что в демонстрационном фильме у нас теперь есть несколько звезд, все в разных случайных позициях. Все они имеют идентичные копии выражения случайной позиции, поэтому вам может быть интересно, почему они имеют разные позиции. Оказывается, для любого заданного случайного начального числа сгенерированные случайные значения будут уникальными для каждого слоя. Внутри After Effects каким-то образом изменяет начальное значение, чтобы оно было уникальным для каждого слоя, композиции, свойства, эффекта и т. д.


🖤Спасибо за внимание!

Блог Motion Richy — Создавай иначе!