Я знаю, що це давнє запитання, але я думаю, що у відповідях, що даються досі, було пропущено щось. У первісному питанні, ракеті (або будь-якій іншій) було сказано, щоб прискорити до положення цілі. Кілька відповідей вказували на те, що це було неправильно, і вам слід прискоритись до того місця, де ви думаєте, що ціль буде в якийсь пізній час. Це краще, але все ж неправильно.
Те, що ви насправді хочете зробити, - це не прискорити рух до цілі, а рухатися до цілі. Спосіб подумати над цим - встановити бажану швидкість, спрямовану на ціль (або проекцію розташування цілі), а потім розібратися, яке прискорення ви могли найкраще застосувати (враховуючи будь-які обмеження, тобто ракета, ймовірно, не може прискорити безпосередньо у зворотному напрямку) для досягнення бажаної швидкості (пам'ятаючи, що швидкість - вектор).
Ось відпрацьований приклад, який я реалізував сьогодні вранці, в моєму випадку для гравця AI в спортивній симуляційній грі, де гравець намагається переслідувати свого суперника. Рух регулюється стандартною моделлю 'удар-дрейф', де прискорення застосовуються на початку часового кроку для оновлення швидкостей, а потім об’єкти дрейфують із такою швидкістю протягом тривалості часового кроку.
Я б опублікував виведення цього, але я виявив, що на цьому сайті не підтримується розмітка математики. Бу! Вам просто доведеться вірити, що це оптимальне рішення, маючи на увазі, що у мене немає обмежень щодо напрямку прискорення, що не стосується об'єкта ракетного типу, тому це вимагало б додаткових обмежень.
Код є в 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) обчислює зворотний загар 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)
Я також перевіряю нову швидкість проти максимальної швидкості, залежної від гравця, і обмежую її. У випадку з ракетою, автомобілем або чимось із максимальною швидкістю повороту (у градусах на галочку) ви можете просто подивитися на поточний кут руху проти обчисленого ідеалу, і якщо ця зміна більша від дозволеної, просто змініть кут на якомога більше до ідеалу.
Для всіх, хто зацікавлений у виведенні цього, я записав відстань між гравцем та ціллю після часового кроку, з точки зору початкової позиції, швидкості, швидкості прискорення та кута прискорення, а потім взяв похідну щодо кута прискорення. Встановивши, що до нуля, знаходяться мінімуми відстані гравця-цілі після часового кроку як функції кута прискорення, який саме ми хочемо знати. Цікаво, що, хоча швидкість прискорення спочатку була в рівняннях, вона скасовує створення оптимального напрямку незалежним від того, наскільки ви насправді здатні прискорити.