Решение проблемы с ошибкой Invalid numeric result

Внезапно обнаружилось решение для проблемы, долго меня мучавшей — ошибка типа «Invalid numeric result» при применении классического выражения для баунса.

5zo-3gWk5kc

Короткое решение — просто сократите длину композиции. Ошибка появляется на очень длинных композициях. Удалось повторить при длине 2 минуты и decay равным 7 или больше.

Длинное объяснение — В классическом баунсе мы делим синус на экспоненту в степени времени, умноженной на коэффициент затухания.

Всё зло в знаменателе, ведь именно он дает нам деление на ноль.
Чем больше время, тем больше знаменатель, и в конечном итоге мы вылетим за пределы максимального значения переменной типа Number в JavaScript, на 64-битных системах это 2 в 53 степени, Javascript присвоит такому числу значение Infinity и мы поделим на ноль (JS странный). А может и не ноль, попробуйте поделить число на строку. Так то.

Почему ошибку не видно сразу?

Дело в том, что АЕ сперва обсчитывает полностью выражение на весь таймлайн, а затем хранит его у себя где-то в кэше, так что пока он считает — ошибки не возникнет.

Это помогло уже минимум одному человеку. Надеюсь, поможет еще кому-нибудь, потому что с таким вопросом обращались не раз.

There are 3 comments

  1. Сергей

    Спасибо. Мне тоже помогло. Второй.!!!
    частенько меня доставала эта ошибка. У меня обычно композиции были 3,5 -5 минут…на длину песни

  2. Шуриксандр Давыдов

    Ребята, а что делать, если длину композиции нельзя менять, если это видео с готовым хронометражем. Вешаю коротенькие плашки с затуханием. У меня ошибка возникает при отправке в Media Encoder, при обычном рендере в AE всё ок.
    Есть ли ещё какой-то способ справиться с недугом?

  3. Кирилл Ахмеров

    Я немного модернизировал скрипт таким образом.
    Вот эту строчку

    value + v*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t);

    Заменил этими тремя строками:

    temp=Math.exp(decay*t);
    if (temp>4500000000000000) {temp=4500000000000000};
    value + v*amp*Math.sin(freq*t*2*Math.PI)/temp;

    Получается, что знаменатель высчитывается заранее, если число получается больше чем 2^52, то знаментаелю приписывается собственно 2^52. И в таком случае знаменатель не выходит за возможнве границы переменной типа Number и все ок.
    Пока все работает отлично.
    Берите, проверяйте.

Comments are closed.