Расчет скорости движущегося объекта на основе его расстояния до цели

Я пишу симуляцию, в которой объект движется в двухмерном мире к целевой позиции, сохраняемой как вектор 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;
Другие вопросы по тегам