Відповіді:
Параболічна траєкторія функція визначається як:
Fx = Vox*t + Ox;
Fy = -0.5 * g * t * t + Voy*t + Oy;
Відомі значення:
P: the target point.
O: the origin point.
g: gravity.
t: time needed to impact.
Невідомі значення:
Vo: Initial Velocity
Для обчислення "Vo" ми можемо надати значення функції F:
't' = flight time 'duration'
'F' = target point 'P'
(Px-Ox)
Vox = --------
duration
Py + 0.5* g * duration * duration - Oy
Voy = ---------------------------------------
duration
Тепер ви можете отримати всі значення для досягнення цілі з початком, даючи значення t у рівняння F:
When t = 0 => F == O (Origin)
When t = duration => F == P (Target)
Нещодавно мені довелося вирішити подібну проблему, і я придумав два рішення, засновані на формулі, яку я знайшов на згадуваній сторінці Вікіпедії «Дан Людина»: Траєкторія снаряду
У цьому рішенні вам фактично потрібен або фіксований кут запуску, або швидкість x. Швидкість Y не потрібна, коли ми запускаємо снаряд під певним кутом.
Рішення 1, кут пуску зафіксовано, обчисліть швидкість:
g = 9.81; // gravity
x = 49; // target x
y = 0; // target y
o = 45; // launch angle
v = (sqrt(g) * sqrt(x) * sqrt((tan(o)*tan(o))+1)) / sqrt(2 * tan(o) - (2 * g * y) / x); // velocity
Рішення 2, швидкість фіксована, обчисліть кут запуску:
g = 9.81; // gravity
v = 40; // velocity
x = 42; // target x
y = 0; // target y
s = (v * v * v * v) - g * (g * (x * x) + 2 * y * (v * v)); //substitution
o = atan(((v * v) + sqrt(s)) / (g * x)); // launch angle
У моєму випадку ці рішення спрацювали досить добре.
Якщо вам не байдуже, чи це математично правильно, лише те, що він виглядає достатньо правильним, обчисліть прямий шлях і змусьте снаряд слідувати цим шляхом, але "просуньте його" по нормалі цієї лінії як функцію відстані вниз відрізок лінії, тому він піднімається в міру наближення до середини відрізка і падає, коли відходить від середини відрізка лінії.
Ви можете використовувати для цього синусоїду, використовуючи діапазон градусів від -90 до +90 (де -90 - ліва точка на відрізку лінії, 90 - права точка, і ви лепнете в середині), і помножте результат постійним масштабуванням.
Якщо вам потрібна чисто правильна математична / фізична відповідь, це не допоможе. Якщо ви цього не зробите, це, ймовірно, може спрацювати досить добре для вас!
Не забувайте, що ігрове програмування - це використання ілюзій, які виглядають правильно (і дешевше обчислюються), а не реалізмом.
Якщо вам просто потрібно щось, що є майже правильним і має фіксовану швидкість, ви можете використовувати цей дуже спрощений метод.
distance = to.x - from.x;
angleToPoint = atan2(to.y - from.y, to.x - from.x);
distanceFactor = 1/1000;
angleCorrection = (PI*0.18) * (distance * distanceFactor);
velocity.X = cos(angleToPoint+angleCorrection) * power;
velocity.Y = sin(angleToPoint+angleCorrection) * power;
Відстань може бути негативною, але вона все одно спрацює, оскільки кут залежить і від відстані. Якщо відстань негативна, кут, який потрібно додати, також негативний.
Вам потрібно буде пограти з distanceFactor, щоб знайти потрібне значення. Це залежить від сили тяжіння та потужності снаряда. Він повинен бути близько 1, розділеного на максимальну відстань, яку може пройти снаряд.