Демпфирующий эффект системы Spring-Mass (или это ElasticEase?)

Я пытаюсь эмулировать анимационный эффект в коде (почти любой язык будет делать то, что кажется математикой, а не языком). По сути, это эмуляция системы масс-спринг. Я смотрел на WPF/Silverlight's ElasticEase и это выглядит довольно близко к тому, что я ищу, но не совсем.

Прежде всего, вот что я ищу - объект, перемещаясь на определенное количество секунд, ударяя по местоположению и сразу же замедляясь, на определенное количество секунд останавливается в той же самой точке, где было применено демпфирование. Так что, чтобы это визуализировать, скажем, у меня есть холст 600w/900h, и у меня есть квадрат, который начинает анимировать от 900px до 150px в TranslateTransform.Y. Это занимает 4 секунды, чтобы достичь 150px высоты (187.5px в секунду), на этом этапе он сразу же затухает и только путешествует около 35px больше на 0.4 секунды (87.5px в секунду) до 115px высоты, затем отскакивает вниз на 1 секунду до 163px высоты (48px и 48px в секунду) и затем отскакивает обратно до 146px (17px и 17px в секунду) и так далее до тех пор, пока колебания не замедлят его до последнего места покоя 150px. Период колебаний составляет 16 секунд.

Пример, который я описал выше, это левый верхний синий прямоугольник: enter image description here

Вот что я узнаю заранее - расстояние между пикселями и количество секунд, необходимое для того, чтобы добраться из точки A в точку B, количество секунд для оцилляции. Такие вещи, как масса, кажется, не имеют значения.

Я попробовал ElasticEase и, кажется, проблема в том, что я не могу заставить объект перемещаться без ослабления в течение 4 секунд, а затем "отскакивать" в течение следующих 16 секунд. Весна .Springiness также всегда слишком высока, даже если я установил ее на действительно высокое число вроде 20.

ILSpy show имеет свою функцию как:

protected override double EaseInCore(double normalizedTime)
        {
            double num = Math.Max(0.0, (double)this.Oscillations);
            double num2 = Math.Max(0.0, this.Springiness);
            double num3;
            if (DoubleUtil.IsZero(num2))
            {
                num3 = normalizedTime;
            }
            else
            {
                num3 = (Math.Exp(num2 * normalizedTime) - 1.0) / (Math.Exp(num2) - 1.0);
            }
            return num3 * Math.Sin((6.2831853071795862 * num + 1.5707963267948966) * normalizedTime);
        }

Я включил 2 видео и файл Excel в папку zipped на DropBox . Я думаю, что этот вопрос будет больше работы в процессе, так как люди задают более уточняющие вопросы.

(ДИСКЛЕЙМЕР: Я не знаю, о чем я говорю, когда речь идет о многом из этого)

12
задан Todd Main 9 September 2011 в 17:13
поделиться