编程从当前速度矢量到目标矢量的推力的平滑变化

use*_*526 7 math physics vector angle linear-algebra

TL;博士:"我不知道如何计算一个矢量与另一个矢量之间的推力的平滑过渡."

我正在编写一个简单的游戏,敌人在开放空间(没有墙壁)追逐玩家.我正在独立计算敌人的x和y速度,如果他们将它们朝向玩家的方向加速它们,并且如果它们走错了路线就会迅速减速(例如EnemyVelocity.x> 0&player.x <enemy.x) ,然后是EnemyVelocity.x - 2.)

虽然游戏玩法试图躲避敌人是非常有趣的,但我希望让敌人使用适当的物理行为.我目前正在做的是让敌人根据他们和玩家之间的角度设置他们的推力(想象一艘宇宙飞船),让他们的推力加速到最大速度(计算EnemyVelocity三角形的c侧).一旦发生这种情况,我不确定推力调整的最佳方式.如果我没有留下最大速度,敌人加速很好,但很容易超过玩家,然后需要很长时间才能获得足够的动力回到玩家的方向.

我想要发生的是让敌人在前往玩家的路上不断调整他们的速度,无论他们身在何处(我不希望他们预测你将在哪里).然后,当他们错过了球员时,我想要相同的推力和加速度公式来重新调整他们的速度并将它们发送回玩家.

我认为这将涉及两个向量:一个是敌人目前正在旅行的地方,另一个是敌人想要旅行的地方(将他们直接带到玩家的向量).我不确定如何计算一个矢量与另一个矢量之间的推力的平滑过渡.

任何提示,公式或问题将不胜感激!谢谢Stack Overflow.

Ima*_*ist 2

这一切都回到牛顿方程:

F = m * a
s = s_o + v * t + a * t^2 / 2
v = v_o + a * t
Run Code Online (Sandbox Code Playgroud)

在本例中F, 是力(推力),a是加速度,m是船舶的质量。 s是当前位置,s_o是原始位置,v是速度,t是当前时间。

当然,这是沿着一条直线,所以如果你想转换为二维或三维,你必须做一些数学运算。 Fsv、 和a都是向量,这意味着它们的方向同样重要。从技术上讲t,它也是一个向量,但由于时间通常只向一个方向移动,所以我们不必担心这一点。

2d:
F^2 = F_x^2 + F_y^2 (use Pythagorean theorem to split force into components)
F_x = m * a_x
F_y = m * a_y
s_x = s_o_x + v_x * t + a_x * t^2 / 2
s_y = s_o_y + v_y * t + a_y * t^2 / 2
v_x = v_o_x + a_x * t
v_y = v_o_y + a_y * t

3d:
F^2 = F_x^2 + F_y^2 + F_z^2 (surprisingly, this works)
F_x = m * a_x
F_y = m * a_y
F_z = m * a_z
s_x = s_o_x + v_x * t + a_x * t^2 / 2
s_y = s_o_y + v_y * t + a_y * t^2 / 2
s_z = s_o_z + v_z * t + a_z * t^2 / 2
v_x = v_o_x + a_x * t
v_y = v_o_y + a_y * t
v_z = v_o_z + a_z * t
Run Code Online (Sandbox Code Playgroud)

现在,为了将速度调整到玩家的方向,您需要一个固定的总力 ( F) 来改变当前朝向玩家的速度。在物理学中,事情不会立即发生,但你的目标应该是最小化变化发生的时间(“t”)。

这为您提供了一个关于您的当前位置((s_o_x,s_o_y)(s_o_x,s_o_y,s_o_z))和对手当前位置或您的目标位置((s_x,s_y)(s_x,s_y,s_z))的方程,以获得您的目标速度(忽略加速度)。

v_x = (s_x - s_o_x) / t
v_y = (s_y - s_o_y) / t

v_x = (s_x - s_o_x) / t
v_y = (s_y - s_o_y) / t
v_z = (s_z - z_o_y) / t
Run Code Online (Sandbox Code Playgroud)

我们可以用这个代替我们的另一个方程:

(s_x - s_o_x) / t = v_o_x + a_x * t
(s_y - s_o_y) / t = v_o_y + a_y * t

(s_x - s_o_x) / t = v_o_x + a_x * t
(s_y - s_o_y) / t = v_o_y + a_y * t
(s_z - z_o_y) / t = v_o_z + a_z * t
Run Code Online (Sandbox Code Playgroud)

然后我们求解加速度(这与力有关,这正是我们要计算的)。

(s_x - s_o_x) / t^2 - v_o_x / t = a_x
(s_y - s_o_y) / t^2 - v_o_y / t = a_y

(s_x - s_o_x) / t^2 - v_o_x / t = a_x
(s_y - s_o_y) / t^2 - v_o_y / t = a_y
(s_z - z_o_y) / t^2 - v_o_z / t = a_z
Run Code Online (Sandbox Code Playgroud)

将其代入力方程:

F_x = m * (s_x - s_o_x) / t^2 - m * v_o_x / t
F_y = m * (s_y - s_o_y) / t^2 - m * v_o_y / t

F_x = m * (s_x - s_o_x) / t^2 - m * v_o_x / t
F_y = m * (s_y - s_o_y) / t^2 - m * v_o_y / t
F_z = m * (s_z - z_o_y) / t^2 - m * v_o_z / t
Run Code Online (Sandbox Code Playgroud)

现在解决t

t = (-m * v_o_x +/- sqrt(m^2 * v_o_x^2 - 4 * F_x * m * (s_x - s_o_x))) / 2 / F_x
t = (-m * v_o_y +/- sqrt(m^2 * v_o_y^2 - 4 * F_y * m * (s_y - s_o_y))) / 2 / F_y

t = (-m * v_o_x +/- sqrt(m^2 * v_o_x^2 - 4 * F_x * m * (s_x - s_o_x))) / 2 / F_x
t = (-m * v_o_y +/- sqrt(m^2 * v_o_y^2 - 4 * F_y * m * (s_y - s_o_y))) / 2 / F_y
t = (-m * v_o_z +/- sqrt(m^2 * v_o_z^2 - 4 * F_z * m * (s_z - s_o_z))) / 2 / F_z
Run Code Online (Sandbox Code Playgroud)

时代应该会聚,所以时代才会平等!这为我们提供了每个坐标(平面和球体)的方程组。请注意,有多个可能的值,但有些涉及虚数,因此您必须消除这些解决方案:

(-m * v_o_x +/- sqrt(m^2 * v_o_x^2 - 4 * F_x * m * (s_x - s_o_x))) / 2 / F_x
= (-m * v_o_y +/- sqrt(m^2 * v_o_y^2 - 4 * F_y * m * (s_y - s_o_y))) / 2 / F_y
F^2 = F_x^2 + F_y^2

(-m * v_o_x +/- sqrt(m^2 * v_o_x^2 - 4 * F_x * m * (s_x - s_o_x))) / 2 / F_x
= (-m * v_o_y +/- sqrt(m^2 * v_o_y^2 - 4 * F_y * m * (s_y - s_o_y))) / 2 / F_y
= (-m * v_o_z +/- sqrt(m^2 * v_o_z^2 - 4 * F_z * m * (s_z - s_o_z))) / 2 / F_z
F^2 = F_x^2 + F_y^2 + F_z^2
Run Code Online (Sandbox Code Playgroud)

解出(F_x,F_y)(F_x,F_y,F_z)坐标,您就得到了所需的力。

如果您有任何疑问或发现我的数学错误,请告诉我。