Я пытался решить эту проблему в течение многих дней теперь, но я должен пропускать что-то.
Известные переменные:
vi = Начальная Скорость
t = Продолжительность анимации
d = Расстояние.
скорость конца должна всегда быть нулем
Функция я пытаюсь создать: D (0... t) = текущее расстояние в течение данного времени
Используя эту информацию я хочу смочь создать кривую плавной анимации с переменной скоростью (ease-in/ease-out).
Анимация должна смочь простота - в от начальной скорости.
Анимация должна быть точно t секундами и должна быть перемещением точно d единицы.
Кривая должна склониться к средней скорости с ускорением, возникающим вначале и частями конца кривой.
Я открыт для дополнительных переменных конфигурации.
Лучшее, которое я смог придумать, является чем-то, что не включает в начальную скорость. Я надеюсь, что кто-то более умный может выручить меня.;)
Спасибо!
p.s. Я работаю с вариантом ECMAScript
Вот другое решение, где нет временного интервала, в котором скорость постоянна. Вместо этого скорость как функция времени является полиномом второго порядка, а ускорение линейно во времени (положительное в начале и отрицательное в конце). Может, ты попробуешь.
Позвольте мне немного переименовать ваши переменные. Пусть
Мы ищем плавную функцию v (t) (скорость как функция времени) такая, что:
С (вогнутым ) полином второго порядка, мы можем удовлетворить всем трем ограничениям. Следовательно, пусть
v (t): = at ^ 2 + bt + c
и давайте решим относительно a, b, c. Первое ограничение v (0) = V сразу дает c = V. Второе ограничение читает
aT ^ 2 + bT + V = 0
С другой стороны, интеграл от v (t ) равно d (t) = 1/3 при ^ 3 + 1/2 bt ^ 2 + Vt (это расстояние, пройденное за время t), поэтому третье ограничение имеет вид
d (T) = 1/3 a T ^ 3 + 1/2 b T ^ 2 + VT = D
Последние два уравнения кажутся запутанными, но это всего лишь два линейных уравнения с двумя неизвестными a, b, и они должны быть легко разрешимы. Если я сделал свои вычисления правильно, окончательный результат будет
a = 3V / T ^ 2 - 6D / T ^ 3, b = 6D / T ^ 2 - 4V / T
Если вы замените a, b, c в выражении d (t) вы получаете пройденное расстояние как функцию времени.
Я полагаю, что вы хотите решить свою проблему в 3 частях.
Во-первых, вам нужно найти минимальную скорость, необходимую для прохождения расстояния за время T.
Это будет довольно просто (D/t) = v(min)
Это предполагает мгновенное ускорение от v(initial) до v(min) и снова замедление в течение периода времени 0s в начале и конце.
Например, допустим, ваша скорость v(i) составляет 5px/s. вам нужно движение на 100px за 10 секунд.
v(min) = 100px/10s = 10px/s
Во-вторых, вам нужно плавное ускорение от v(initial) до v(min). это займет некоторый период времени t(acc). Если предположить, что ускорение и замедление будут равны, то можно просто посчитать для одного из них, а затем умножить на 2. Мы можем назвать функцию, которая описывает расстояние, пройденное во время ускорения, D(accel).
Для начала упростим задачу и скажем, что мы хотим, чтобы продолжительность ускорения была 1 с,
поэтому уравнение для общего пройденного расстояния будет иметь вид D(total) = D(accel) + D(v(max) )
Когда вы знаете, что D(accel) рассчитан на 2 с, вы можете рассчитать
D(accel) = ( V(ini) + V(max) ) /2) * (2seconds)
и
D(v(max)) = V(max) * 8s
решив для V(max), получаем
100px = D(accel) + D(v(max))
100px = ( 5px/s + VMax) /2 * (2s)) + VMax *8s
100px = 5px + (Vmax * 1s) + Vmax *8s
95px = 9Vmax *s
VMax = 95px/9s
VMax = 10.556px/s
Теперь вы можете вернуться назад и заменить окно ускорения в 1s формулой, которая определяет окно ускорения как % от общего периода времени или что-то еще.
Также обратите внимание, что для целей анимации вам придется разбить 10.556px/s на движения в пикселях на кадр и соответствующим образом учесть время.
Использование постоянных ускорений:
Определения:
Vi - Initial velocity
Va - Average velocity
Vo - Ending velocity
D - Total distance to be traveled
T - Total time for travel
t1 - Acceleration time from beginning to Va
t2 - Acceleration time from Va to Vo
Уравнение, которое необходимо решить:
(Vi+Va)/2*t1 + Va*(T-t2-t1) + (Va+Vo)/2*t2 = D
Вы должны решить, сколько времени будет начальное ускорение (t1 ) и окончательное ускорение (t2), и тогда у вас останется только одно неизвестное -> Va, которое можно легко решить.
РЕДАКТИРОВАТЬ : найти расстояние как функцию времени:
Итак, теперь, когда вы знаете скорости, легко вычислить пройденное расстояние:
D(t) = Vi*t + 0.5*t^2*(Va-Vi)/t1 {0<t<t1}
D(t) = Va*(t-t1) + D1 {t1<t<t3}
D(t) = Va*(t-t3)+0.5*(t-t3)^2*(Vo-Va)/t2 + D2 {t3<t<T}
где t3 = (T-t2) , D1 и D2 - это расстояние, пройденное в конце первого и второго сегментов, которое можно найти с помощью соответствующих функций:
D1 = 0.5*(Va+Vi)*t1
D2 = D1 + Va*(t3-t1)
РЕДАКТИРОВАТЬ 2 : Решение для Va:
(Vi+Va)/2*t1 + Va*(T-t2-t1) + (Va+Vo)/2*t2 = D
Помните, что t1 и t2 являются параметры задачи, которые вы выбираете. Вы сами решаете, в какой части движения объект ускоряется и замедляется. Допустим, t1 = t2 = 0,1 * T. Затем подстановка дает:
(Vi+Va)/2*(0.1T) + Va*(T-(0.1T)-(0.1T)) + (Va+Vo)/2*(0.1T) = D
Va*(0.1T/2 + T-0.1T-0.1T + 0.1T/2) + Vi*(0.1T)/2 + Vo*(0.1T)/2 = D
Va*(0.9T) + Vi*(0.05T) + Vo*(0.05T) = D
Va*(0.9T) = D - Vi*(0.05T) + Vo*(0.05T)
Va = (D - (Vi + Vo)*(0.05T)) / (0.9T)
Понятно?
abustin, поскольку вам не нравится решение с 3 сегментами, вы можете попробовать рассмотреть кривые Безье для решения этой проблемы. Кривая Безье может быть использована для интерполяции времени и расстояния, поэтому вы можете определить несколько контрольных точек на концах движения для создания ускорения, а средний "сегмент" будет определен таким образом, что скорость будет близка к постоянной. Использование сплайнов тоже возможно.