2009-06-03 3 views
1

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

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

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 

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

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

ответ

6

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

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

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

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

+0

У этой проблемы есть такая же проблема, как и моя вторая реализация. Попробуйте сами. – Kai

+0

@Kai: umm, no it should not ... – ephemient

+0

А, моя реализация была неправильной, а не этот алгоритм (способ выглядеть глупо). Благодаря! – Kai

3

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

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

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

0

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

3

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

х = радиус * Cos (Theta)
Y = радиус * Sin (тета)

тета (т) = theta (0) + omega (0) * t + 0,5 * alpha * t^2

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

+1

Это предполагает, что альфа остается постоянным. Конечно, вы можете сделать это кусочно-непрерывным образом - запустите его до времени T, а затем повторно инициализируйте в этом состоянии. –

0
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 
4

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

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

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

скорость (т) = т * согл + о себе [т = 0].

и

угол (т) = т * согласно/2 + Vel [т = 0] * T + угол [т = 0].

Затем вы можете рассчитать свое плечевое положение с sin и cos угла.

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

+0

Это отличное объяснение того, что я делаю неправильно, спасибо, что помогли мне понять это! – Kai

2

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

time * speed 

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

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

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

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

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

'time * speed' иногда имеет смысл, когда ваши временные шаги не всегда равны (например, если вы работаете с кадром). – ephemient

+0

У вас есть правильная идея. Возможно, вы захотите иметь переменный временной шаг, как в d + = v * delta; v + = a * delta; Конечно, это интеграция Эйлера. Рунге-Кутта будет более точным. –