Расчет скорости движущегося объекта на основе его расстояния до цели
Я пишу симуляцию, в которой объект движется в двухмерном мире к целевой позиции, сохраняемой как вектор target(x,y)
, Положение объекта сохраняется как вектор положения pos(x,y)
также. Объект содержит еще два вектора, желаемую скорость движения dv(x,y)
, а также текущая скорость движения cv(x,y)
, В начале моделирования оба этих вектора скорости являются начальными, т.е. (0,0)
,
Когда объект должен двигаться в направлении целевого положения, я рассчитываю нужный вектор скорости dv
, нормализуйте его и масштабируйте по значению скорости движения:
dv.set(target).sub(pos).normalize()
dv.scale(speed)
Я хочу, чтобы движение выглядело более реалистичным, поэтому я использую два вектора скорости. dv
говорит на полной скорости, что я хочу переместить объект, и cv
содержит реальную скорость движения объекта
Тогда на каждом кадре (шаг обновления) текущая скорость cv
устанавливается на основе желаемой скорости dv
и значение ускорения acc
, Это делается путем простого вычисления разницы между cv
а также dv
и зажимая эту разницу acc
, Таким образом, объект начинает медленно двигаться и постепенно ускоряться, чтобы в конечном итоге достичь полной скорости.
Пока это работает нормально. Теперь я хочу использовать acc
для замедления, а также. Когда расстояние между pos
а также target
на определенное значение, желаемая скорость dv
должен быть установлен в (0,0)
, так что объект постепенно замедляется, пока не достигнет полной остановки в целевой позиции.
Мой вопрос: как я могу рассчитать, на каком расстоянии мне нужно установить dv
в (0,0)
(то есть сказать системе прекратить движение), чтобы объект правильно замедлялся, чтобы остановиться точно в заданной позиции?
2 ответа
Используйте кинематические уравнения:
vf2 = vi2 + 2 * a * d
vf - ваша конечная скорость или 0 (скорость, по которой вы хотите двигаться)
vi - заданная вами начальная скорость (скорость движения вашего объекта в данный момент).
а ускорение
д расстояние.
Решить за д:
2 * a * d = vf2 - vi2
2 * a * d = 0 - vi2
Предположим, ускорение отрицательно, поэтому умножьте обе стороны на -1
- 2 * | a | * d = vi2
| | это абсолютное значение вашего ускорения (замедление в вашем случае)
- d = vi2 / (2 * | a |)
Вы делаете симуляцию движения с дискретным временем. Один из способов упростить задачу - выполнить расчеты так, чтобы ускорение и замедление были симметричными. Другими словами, расстояние, пройденное при ускорении, должно быть таким же, как и расстояние, пройденное при замедлении. В качестве примера предположим,
- ускорение 5
- максимальная скорость 13
- объект начинает замедляться, как только достигает максимальной скорости
Вот как будет развиваться моделирование с дискретным временем
first tick
old speed = 0
new speed = 5
distance = 5
second tick
old speed = 5
new speed = 10
distance = 15
third tick
old speed = 10
new speed = 13
distance = 28 <-- total distance while accelerating
fourth tick
old speed = 13
distance = 41
new speed = 10 <-- not 8!!!
fifth tick
old speed = 10
distance = 51
new speed = 5
sixth tick
old speed = 5
distance = 56 <-- Yay, twice the distance, we have symmetry
new speed = 0
Здесь есть два ключевых момента
- При ускорении сначала обновляется скорость, а затем обновляется расстояние. В то время как замедление заказа полностью изменено, сначала обновляется расстояние, а затем скорость.
- При замедлении важно сохранять скорректированную скорость как кратное ускорению
На языке программирования C, следующий код может быть использован для обновления скорости во время замедления
if ( old_speed % acceleration != 0 ) // if speed is not a multiple of acceleration
new_speed = old_speed - old_speed % acceleration; // reduce speed to a multiple of acceleration
else // otherwise
new_speed = old_speed - acceleration; // reduce speed by acceleration
Если ускорение и замедление симметричны, то вычисление расстояния замедления аналогично вычислению расстояния ускорения.
distance = acceleration * (1+2+3+ ... +N) + fudge_factor
где
N
являетсяtop_speed / acceleration
усечено до целого числа, например13/5 ==> 2
fudge_factor
является0
если максимальная скорость кратна ускорению, илиtop_speed
иначе
Вычисление можно упростить, отметив, что
1+2+3+ ... +N = N * (N+1) / 2
В C общая пройденная дистанция при замедлении может быть рассчитана следующим образом
int top_speed = 13;
int acceleration = 5;
int N = top_speed / acceleration; // Note: in C, integer division truncates
int fudge = 0;
if ( top_speed % acceleration != 0 )
fudge = top_speed;
int distance = acceleration * (N * (N+1)) / 2 + fudge;