Математическое уравнение для расчета различных скоростей для затухающей анимации - PullRequest
4 голосов
/ 11 июня 2009

Я пытаюсь добавить эффект затухания в мою форму, вручную изменяя непрозрачность формы, но у меня возникают некоторые проблемы с вычислением правильного значения для увеличения на значение непрозрачности формы.

Я знаю, что мог бы использовать API AnimateWindow, но он демонстрирует некоторое неожиданное поведение, и я бы предпочел сделать это вручную в любом случае, чтобы избежать любого вызова p /, чтобы позже я мог использовать его в Mono.

Мое приложение поддерживает скорости от 1 до 10. И я вручную рассчитал, что для скорости 1 (самая медленная) я должен увеличить непрозрачность на 0,005, а для скорости 10 (самая быстрая) я должен увеличить на 0,1. Что касается скоростей от 1 до 10, я использовал следующее выражение для вычисления правильного значения:

double opSpeed = (((0.1 - 0.005) * (10 - X)) / (1 - 10)) + 0.1; // X = [1, 10]

Я подумал, что это может дать мне линейное значение, и это будет нормально. Однако для X, равного 4 и выше, это уже слишком быстро. Больше, чем должно быть. Я имею в виду, скорости между 7 и 10, я едва вижу разницу, и скорость анимации с этими значениями должна быть немного больше разнесены

Обратите внимание, что я все еще хочу, чтобы самый быстрый прирост был 0,1, а самый медленный 0,005. Но мне нужно, чтобы все остальные были линейными между ними.

Что я делаю не так?

РЕДАКТИРОВАТЬ: На самом деле имеет смысл, почему это работает, например, для фиксированного интервала между приращениями, скажем, несколько миллисекунд, и с уравнением выше, если X = 10, то opSpeed ​​= 0,1 и если X = 5, то opSpeed ​​= 0,47. Если мы подумаем об этом, значение 0,1 будет повторяться 10 раз, а значение 0,47 - только двойным. Для такого небольшого интервала, составляющего всего несколько миллисекунд, разница между этими значениями не так велика, чтобы различать скорости от 5 до 10.

Ответы [ 5 ]

6 голосов
/ 11 июня 2009

Я думаю, что вы хотите:

0.005 + ((0.1-0.005)/9)*(X-1)

для X в диапазоне от 1-10

Это дает линейную шкалу, соответствующую 0,005 при Х = 1 и 0,1 при Х = 10

После комментариев ниже я также включил свой ответ, подходящий для геометрического ряда вместо линейного масштаба.

0.005 * (20^((X-1)/9)))

В результате получается геометрическое отклонение, соответствующее 0,005 при X = 1 и 0,1 при X = 10

После гораздо большего обсуждения, как видно из комментариев ниже, обновления следующие:

@ Nazgulled обнаружил следующее соотношение между моими геометрическими рядами и ручными значениями, которые ему действительно необходимы для обеспечения плавной анимации затухания.

Отношения были следующими: Я ♥ Графики! :) http://i41.tinypic.com/9v8lqg.jpg

Что означает, что геометрический / экспоненциальный ряд - это путь.

После моих часов попыток найти подходящую кривую, подходящую к правому графику, и вывести правильное уравнение, @Nazgulled сообщил мне, что Wolfram | Alpha делает это. Серьезно удивительно. :)

http://tinyurl.com/lthn9v

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

4 голосов
/ 11 июня 2009

Ваша проблема проистекает из того факта, что человеческий глаз не является линейным в своем ответе; чтобы быть точным, глаз не регистрирует разницу между светимостью от 0,05 до 0,10, которая совпадает с разницей светимости между 0,80 и 0,85. Вся тема сложна; Вы можете искать фразу «гамма-коррекция» для получения дополнительной информации. В общем, вы, вероятно, захотите найти уравнение, которое эффективно «гамма-корректирует» для реакции человеческого глаза, и использовать его в качестве функции затухания.

2 голосов
/ 11 июня 2009

Это на самом деле не ответ, но я просто укажу, что все, кто до сих пор писал, включая оригинальный вопрос, все публикуют одно и то же уравнение. Так что с четырьмя независимыми выводами, возможно, мы должны предположить, что уравнение, вероятно, было правильным.

Я выполнил алгебру, но вот код для проверки (в Python, кстати, со смещениями, добавленными для разделения кривых:

from pylab import *

X = arange(1, 10, .1)

opSpeed0 = (((0.1 - 0.005) * (10 - X)) / (1 - 10)) + 0.1   # original
opSpeed1 = 0.005 + ((0.1-0.005)/9)*(X-1)     # Suvesh
opSpeed2 = 0.005*((10-X)/9.) + 0.1*(X-1)/9.  # duffymo

a = (0.1 - 0.005) / 9 #= 0.010555555555...    # Roger
b = 0.005 - a        #= -0.00555555555...
opSpeed3 = a*X+b

nonlinear01 = 0.005*2**((2*(-1 + X))/9.)*5**((-1 + X)/9.)


plot(X, opSpeed0)
plot(X, opSpeed1+.001)
plot(X, opSpeed2+.002)
plot(X, opSpeed3+.003)
plot(X, nonlinear01)
show()

Кроме того, по просьбе Назгулледа я включил нелинейную кривую, предложенную Сувешем (которая, между прочим, также довольно похожа на кривую гамма-коррекции, как предложено McWafflestix). Нелинейное уравнение Сувеша находится в коде как nonlinear01.

alt text

1 голос
/ 11 июня 2009

Если я понимаю, что вы ищете, вы хотите уравнение линии, которая проходит через эти две точки на плоскости: (1, 0,005) и (10, 0,1). Общее уравнение для такой линии (если она не вертикальная) имеет вид y = ax + b. Включите две точки в это уравнение и решите получившийся набор из двух линейных уравнений, чтобы получить

 a = (0.1 - 0.005) / 9 = 0.010555555555...
 b = 0.005 - a        = -0.00555555555...

Затем для каждого целого числа x = 1, 2, 3, ..., 10 вставьте x в y = ax + b, чтобы вычислить желаемое значение y.

1 голос
/ 11 июня 2009

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

Вы хотите, чтобы скорость изменения непрозрачности была линейной функцией скорости:

o (v) = o1 * N1 (v) + o2 * N2 (v), так что 0 <= v <= 1 и o (v1) = o1 и o (v2) = o2. </p>

Если мы выберем N1 (v) равным 1-v и N2 (v) = v, мы получим то, что вы хотите:

o (v) = o1 * (1-v) + o2 * v

Итак, вставьте ваши значения:

v = (u-1) / (10-1) = (u-1) / 9

o1 = 0,005 и o2 = 0,1

Итак, функция должна выглядеть так:

  1. o (u) = 0,005 * {1- (u-1) / 9} + 0,1 * (u-1) / 9
  2. o (u) = 0,005 * {(9-u + 1) / 9} + 0,1 * (u-1) / 9
  3. o (u) = 0,005 * {(10-u) / 9} + 0,1 (u-1) / 9

Вы можете упростить это, пока не получите простую формулу для o (u), где 1 <= u <= 10. Должно работать нормально. </p>

...