Изменение скорости кругового движения - PullRequest
1 голос
/ 03 июня 2009

Я ищу способ плавного увеличения или уменьшения скорости кругового движения.

Используя параметрическое уравнение круга, я могу перемещать объект по кругу во времени:

x = center_x + radius * sin(time * speed)
y = center_y + radius * cos(time * speed)

Проблема с этим подходом заключается в том, что я не могу просто сделать speed = speed + 1, чтобы ускорить объект, потому что это приводит к резким движениям. Это имеет смысл, поскольку значения x и y пересчитываются каждый кадр на основе абсолютных значений, а не относительно предыдущей позиции объекта.

Другой подход может состоять в том, чтобы использовать вектор, который представляет скорость объекта, а затем вместо него применить круговое движение:

v_x = radius * sin(time * speed)
v_y = radius * cos(time * speed)
x = x + v_x
y = y + v_y

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

Одна реализация, о которой я могу подумать, может сработать, это использовать вектор, который указывает от объекта к центру круга. Затем я мог вычислить касательную окружности в положении объекта, используя перпендикулярный вектор, нормализовать его и масштабировать по скорости. Я еще не реализовал это, потому что это кажется излишним для такой проблемы, поэтому, пожалуйста, дайте мне знать, если существует более простое решение. Спасибо!

Ответы [ 7 ]

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

Скорость - это скорость изменения угла, изменение скорости влияет только на изменение угла за последний интервал, поэтому:

delta = time - lastTime
angle = angle + delta * speed

x = center_x + radius * sin(angle)
y = center_y + radius * cos(angle)

где lastTime должно содержать время последнего цикла, понимаете?

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

Вы сказали это сами: вы хотите изменить угловую скорость . Теперь изменение угловой скорости в реальном мире ограничено угловой инерцией объекта. Это означает, что он не может быть «дискретным» с шагом 1.

Скорее, угловая скорость является интегралом от углового ускорения. Угловое положение является интегралом от угловой скорости.

Так что для постоянного углового ускорения можно сказать

скорость (t) = t * acc + vel [t = 0] .

и

угол (t) = t 2 * acc / 2 + vel [t = 0] * t + angle [t = 0] .

Затем вы можете вычислить вашу позицию в корзине с грехом и cos угла.

Угловое ускорение может варьироваться (вполне) дискретно.

3 голосов
/ 03 июня 2009

Для плавного увеличения угловой скорости необходимо добавить угловое ускорение

x = радиус * cos (тета)
у = радиус * грех (тета)

тета (т) = тета (0) + омега (0) * т + 0,5 * альфа * т ^ 2

где t - время, theta (0) - угловое положение в момент времени 0, omega (0) - угловая скорость в момент времени 0 (будет равно вашему параметру скорости), а alpha - параметр углового ускорения, который выбрать что-то подходящее.

3 голосов
/ 03 июня 2009

Вы не используете ускорение правильно, если вы просто делаете speed = speed + 1. В более общем смысле, вы хотите сделать это:

accel = 1;
speed = speed + (accel * timeDelta);

Кроме того, accel = 1 - довольно большое изменение угловой скорости в радианах - попробуйте меньшее значение, скажем, PI / 16. Если вам нужно, чтобы ускорение было таким большим, и вы хотите минимизировать видимость резких движений, вы можете попробовать использовать размытие движения.

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

Использование

time * speed

указывать, как далеко прошел круг, просто неправильно. Это имеет смысл, только если скорость никогда не меняется.

Вместо этого вам нужно сохранить пройденное расстояние в переменной, а затем увеличить переменную на величину, зависящую от текущей скорости и временного интервала с момента последней прорисовки.

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

v = v + a;
d = d + delta * v;

x = center_x + radius * sin(d)
y = center_y + radius * cos(d)
0 голосов
/ 03 июня 2009
x = center_x + radius * sin(time * speed + offset)
y = center_y + radius * cos(time * speed + offset)

def change_speed(new_speed):
    offset = time * (speed - new_speed) + offset
    speed = new_speed

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

time * old_speed + old_offset == time * new_speed + new_offset
0 голосов
/ 03 июня 2009

Вы должны думать об этом с точки зрения угловой скорости. Вы вычисляете угол, тета, как время * скорость, которая не имеет смысла, если скорость - это обычное чувство скорости, то есть расстояние / время. Угловая скорость - это угол / время (т. Е. Радианы / с или градусы / с). Обычная скорость - это расстояние между начальной и конечной точками / временем после применения угловой скорости.

...