Я знаю, что это старый вопрос, но я думаю, что есть кое-что, что было упущено в ответах, данных до сих пор. В первоначальном вопросе ракете (или какому-то другому) было сказано ускориться в направлении положения цели. В нескольких ответах указывалось, что это было неправильно, и вам следует ускориться до того уровня, который, по вашему мнению, будет достигнут в будущем. Это лучше, но все же неправильно.
То, что вы действительно хотите сделать, это не ускоряться к цели, а двигаться к цели. Чтобы подумать об этом, установите желаемую скорость, указанную на цель (или проекцию местоположения целей), а затем выясните, какое ускорение вы могли бы применить лучше всего (учитывая любые ограничения, которые у вас есть, то есть ракета, вероятно, не может быть ускорена). прямо в обратном направлении), чтобы достичь желаемой скорости (помня, что скорость - это вектор).
Вот рабочий пример, который я реализовал сегодня утром, в моем случае для ИИ игрока в спортивной игре-симуляторе, где игрок пытается преследовать своего противника. Движение регулируется стандартной моделью «удар-дрейф», в которой ускорения применяются в начале временного шага для обновления скоростей, а затем объекты дрейфуют с этой скоростью на протяжении временного шага.
Я бы опубликовал вывод этого, но я обнаружил, что на этом сайте не поддерживается математическая разметка. Бу! Вы просто должны поверить, что это оптимальное решение, учитывая, что у меня нет ограничений по направлению ускорения, что не относится к объектам ракетного типа, поэтому для этого потребуются некоторые дополнительные ограничения.
Код написан на python, но должен быть читаемым на любом языке. Для простоты я предполагаю, что каждый временной шаг имеет длину 1 и выражаю скорость и ускорение в соответствующих единицах, чтобы отразить это.
self.x = # current x co-ordinate
self.y = # current y co-ordinate
self.angle = # current angle of motion
self.current_speed = # current magnitude of the velocity
self.acc # Maximum acceleration player can exert on themselves
target_x = # x co-ordinate of target position or projection of it
target_y = # y co-ordinate of target position or projection of it
vx = self.current_speed * math.cos(self.angle) # current velocity x component
vy = self.current_speed * math.sin(self.angle) # current velocity y component
# Find best direction to accelerate
acc_angle = math.atan2(self.x + vx - target_x,self.y + vy - target_y)
Обратите внимание, что функция atan2 (a, b) вычисляет обратный tan для a / b, но гарантирует, что углы находятся в правильном квадранте круга, что требует знания знака как a, так и b.
В моем случае, когда у меня есть ускорение, я применяю его, чтобы обновить скорость
vx_new = vx + self.acc * math.cos(acc_angle)
vy_new = vy + self.acc * math.sin(acc_angle)
self.current_speed = math.sqrt( vx_new**2 + vy_new**2)
self.angle = math.atan2(vy_new,vx_new)
Я также проверяю новую скорость в зависимости от максимальной скорости игрока и ограничиваю ее. В случае ракеты, автомобиля или чего-либо с максимальной скоростью поворота (в градусах на тик) вы можете просто посмотреть на текущий угол движения в сравнении с вычисленным идеалом, и если это изменение больше допустимого, просто измените угол на как можно больше к идеалу.
Для всех, кто интересуется выводом этого, я записал расстояние между игроком и целью после такта с точки зрения начальной позиции, скорости, скорости ускорения и угла ускорения, а затем взял производную по углу ускорения. Установка этого значения в ноль находит минимумы расстояния до цели игрока после временного шага в зависимости от угла ускорения, что именно то, что мы хотим знать. Интересно, что даже несмотря на то, что скорость ускорения изначально была в уравнениях, она сводит на нет оптимальное направление, не зависящее от того, насколько вы на самом деле способны ускоряться.