Пошук правильної швидкості, щоб AI повернувся, щоб досягти мети


10

У мене є корабель, який рухається з максимальною швидкістю maxSpeedі може повертати rotationSpeedградуси в секунду. Корабель завжди рухається в напрямку, в якому він стикається, а це означає, що чим швидше корабель рухається, тим більший його радіус повороту.

Я знаю свою позицію, і обертання, і ціль.

Я хотів би з’ясувати, чи знаходиться ціль у моєму радіусі повороту з цією швидкістю, чи краще, яка максимальна швидкість, яку я можу подорожувати, для того, щоб зробити поворот до цілі, не постійно кружляючи навколо неї.

Чи існує ефективний спосіб зробити це?

Ось що я зараз думаю: оскільки я знаю, як далеко я подорожую за крок і скільки обертаюсь за крок, я можу зрозуміти, де я буду в наступних двох кадрах. Моє поточне положення - p1, наступне - p2, а потім p3. Я можу взяти перпендикулярні бісектриси (p1, p2) та (p2, p3). Їх точка перетину дасть мені центр кола. Потім я можу перевірити, чи є ціль у тому колі.

Я не впевнений, чи це буде працювати в 3D (я не впевнений, як обчислити сферу за допомогою моїх даних). Це рішення також не дуже допомагає знайти правильну швидкість, з якою рухатись, мені доведеться спробувати кілька разів з різною швидкістю, щоб знайти розумну.

Чи може хтось пролити світло на краще рішення?

Відповіді:


17

Існує два способи, коли контрольований AI блок із обмеженою швидкістю обертання та регульованою швидкістю руху може досягти мети.

По-перше, давайте розглянемо завдання, яке нам постає, щоб ми могли краще зрозуміти це:

введіть тут опис зображення

Якщо гравець рухається і обертається з постійною швидкістю, намагаючись досягти цілі, яка знаходиться з правого або лівого боку, він рухатиметься по колах назавжди, ніколи не стикаючись з ціллю. Дві області, якими гравець обведеться, позначені червоним кольором вище.

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

radius = movementSpeed / rotationSpeedInRadians;
circlesCenterX = unitX + cos(unitAngle + / - PI) * radius;
circlesCenterY = unitY + sin(unitAngle + / - PI) * radius;

Це призводить до положення та радіуса червоних кіл. Ми можемо використати це для визначення того, чи певна мета знаходиться поза досяжністю підрозділу, керованого ШІ, якщо вона продовжує повертатись у напрямку мети.

Щоб дізнатися, чи певний елемент знаходиться в одному з кіл, ми просто обчислюємо відстань від центру кіл:

if ((circleX - goalX)^2 + (circleY - goalY)^2 < radius^2) //goal is within red circle

Для цього є два можливих рішення:

1.

Побудуйте деяку відстань до тих пір, поки мета не вийде за межі круглої червоної області, а потім поверніть повороту, як у моді. Це просто, нехай підрозділ продовжує рухатися, поки чек не повернеться, що мета не в цьому колі. Тоді можна розвернутися.

введіть тут опис зображення

Інший варіант вимагає трохи більше роботи для обчислення:

Проводимо уявну лінію між одиницею AI і ціллю. Використовуючи кут між ними:

angle = Math.atan2(goalY - unitY, goalX - unitX);

Тепер потрібно зробити наступне, щоб обчислити правильну швидкість:

correctSpeed = rotationSpeedInRadians * (distance / 2) / cos(angle);

введіть тут опис зображення

Для того, щоб він працював у 3d-справі:

Знайдіть площину, на якій розташовані наступні три точки:

  1. Точка мети.
  2. Положення AI-блоку в попередньому кадрі.
  3. Поточне положення блоку AI.

Ви можете використовувати цю площину для обчислення швидкості в 2d шляху. Вам просто потрібно перетворити крапки з їх 3d-значень у 2d-значення, вбудовані в їх загальну площину.

Ви можете скористатися цим:

Як перетворити 3D-точку на площині в УФ-координати?


Ідеально! Саме відповідь, на яку я сподівався! Дякую за ваші детальні пояснення, я думаю, що я в змозі екстраполювати це і використовувати його в 3D.
weichsem

@weichsem Я оновив відповідь. Ідея, яку я запропонував, - це знайти загальну 2d рівну, якою вони поділяються, і використовувати її для обчислення правильної швидкості.
AturSams
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.