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

TL;博士:“我不知道如何计算一个向量和另一个推力​​之间的平稳过渡。”

我编程一个简单的游戏,玩家在一个开放的空间(无墙)后,敌人追逐。 我计算了敌人的X和Y的速度独立,加速他们,如果他们在玩家的指导服用,迅速减缓他们,如果他们被错误的方式(如EnemyVelocity.x> 0 player.x <enemy.x会,然后EnemyVelocity.x - 2)

虽然游戏是体面的乐趣试图躲避敌人,这是我的愿望,有循规蹈矩使用适当的物理敌人。 什么我目前做的是有敌人设置的推力(想了飞船)的基础上他们和球员之间的角度,并有自己的推力加速到一个最大速度(计算EnemyVelocity三角形的正面c)。 一旦出现这种情况,我不知道有推力自行调节的最佳方式。 如果我没有留下任何的最大速度,敌人加速很好,但容易超调的球员,然后花很长时间来获得足够的动力回笼,在播放器的方向。

我想发生的情况是有敌人不断调整自己的方式速度的球员,目标,无论他们在(我不想让他们来预测在那里你会)。 然后,当他们错过了的球员,我想为同推力和加速度的公式来调整自己的速度和送他们回到了球员。

我想这将涉及到两个载体:一是这里的敌人正在行驶,以及一个在敌人想要去旅行(的载体,将带他们直接到播放器)。 我不知道如何计算一个向量和另一个推力​​之间的平稳过渡。

任何提示,公式或问题,我们将不胜感激! 谢谢堆栈溢出。

--------------解决方案-------------

这一切又回到牛顿方程:

F = m * a
s = s_o + v * t + a * t^2 / 2
v = v_o + a * t

在这种情况下F是的力(推力), a是加速度,和m是船舶的质量。 s是当前位置s_o是原来的位置v是速度,和t是当前时间。

当然,这是沿着一条直线,所以如果你想转换为二维或三维你就必须做一些数学F s va都是向量,这意味着他们的方向同样重要。 技术上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

现在,调整速度与播放器的方向,你已经有了一个固定的总兵力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

我们可以替代这次我们其他的公式:

(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

然后,我们解决的加速度(这与力,而这正是我们试图来计算)。

(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

插到力方程如下:

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

现在解决的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

本次应收敛,所以时间就等于! 这为我们提供了方程的每个坐标(平面和球体)的系统。 请注意,有多个可能的值,但一些涉及虚数,所以你必须要消除这些解决方案:

(-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

求解(F_x,F_y)(F_x,F_y,F_z)坐标和你有你需要的力量。

让我知道,如果你有任何疑问或如果你发现我的数学错误。

你可以得到你想要确保在速度的平稳变化,而 ​​不是推力的影响。 这样一来,如果敌人过冲的播放器,它可以立即扭转其加速,这将慢下来,并最终推翻其行程的方向。

可以通过每次迭代期间改变速度,由是基于从敌人到播放器的距离少量实现此目的:

while (game_in_progress)
{
// Distance from enemy to player. The larger the
// distance, the greater the acceleration will be.
delta.x = player.x - enemy.x
delta.y = player.y - enemy.y

// Accelerate by changing velocity based on distance,
// where 'scale' is sufficiently small. (Limit v to
// some maximum if you choose; likely to be unnecessary.)
vx += delta.x * scale
vy += delta.y * scale

// Update the enemy's position.
enemy.x += vx
enemy.y += vy
}

通过计算xy独立的价值观,你可以保存自己处理的载体,角度,和同时equiations的头痛。

同样,认识到加速(推进)仅仅是在速度变化,而这又是位置的变化,你可以只使用简单的代数运算,而不是微积分产生离散模拟。

玩的开心!

你需要考虑在适当的物理条件。 你的速度,你要添加的加速。 这是所有有给它 - 加速度是速度的逐渐变化,将吸取敌人对着播放器,允许它过头,减缓(或关闭),然后后脑勺往球员。

加速度测量为d(速度)/时间。 要加快实现玩家在任何时间点,所以每间隔(秒,第二次或不管你选择百),你需要敌人和玩家之间的矢量乘以某个常数,添加到您的速度。

Velocity = Velocity + c * (Player-Enemy vector)

常数C取决于你想如何快速加速实现的球员,多久你正在更新你的速度。

如果你想“上限”敌人的最高速度,以便它不会继续增加其速度的大小无止境,你也可以这样做。

Velocity = Velocity * (Maximum magniture / |Velocity|)

编辑:进一步明确,增加了速度仅仅意味着添加成分的载体。 所以

Vx = Vx + c * Ax
Vy = Vy + c * Ay

其中V是流速,A是加速度。 幅度被测量为sqrt(Vx^2 + Vy^2)即一个直角三角形的斜边。 所以,如果你想敌人的最大速度为m,

Vx = Vx * ( m / sqrt(Vx^2 + Vy^2)
Vy = Vy * ( m / sqrt(Vx^2 + Vy^2)

我写了一个简单的小行星游戏而回说有一个“盟友”舰这将追捕小行星和射击它们。 基本上,它找到了最近的小行星,然后开始转向平稳向它和之后打算。 遗憾的是我没有代码了,但如果没有记错,我想我应该用针戳穿船一点点,每回合,那么如果小行星很远我加速了,但如果它是接近我试图以匹配小行星的运行速度。 这是很酷实际上,和最小代数的参与。

做到这一点的最好办法是采取2弧度值和线性插值之间,搬运包裹。 (可能通过加或减二皮在必要时)。 然后将其转换为单位矢量。 随后乘上速度,你要船,加速,和你去那里!

一个简单的方法(不正确的物理学)是计算你的敌人的“预期的速度”,然后调整敌人的当前速度朝着这个,自扫门前雪不管在上面的限制,或最小速度了。

例如,在一个小的2D游戏,我写(http://wordwarvi.sourceforge.net)有“热寻的导弹。” 它看起来很奇怪,如果导弹停在半空中扭转。 所以我所做的就是如下:我计算“所需的速度”,这是对球员。 这只是“相似三角形”完成。 我发现到播放器X中的距离,并且在Y和whichver越大,我提出“理想(x或y)速度是可能的最大,然后,扩展的另一个,以适应”类似三角形“。注意,这还只是“预期的速度”,而不是目前的速度,我把当前的速度,慢慢调整(通过每帧一点点)对“理想”的速度(虽然所需的速度每帧重新计算为好,)在VX和VY mindimg最低,以防止他们停止半空。

阿呆的算法,但它工作正常(没有人抱怨说,他们太容易,太硬或太不现实了。)

编辑:在重新阅读的问题,我的答案可能不是你追求的是什么。

我已经解决了这样的问题专业,我建议你先从简单的版本,并工作了。 确保你每一步预期的行为,然后再尝试下。

  1. 该导引头寻找一个固定的目标在一个维度的起源。 这是正确的,一个维度。 它可以推力来回在x轴和它试图获得为x = 0。 推进器没有节流(像一个固体火箭),但失主可以在任一方向指向它。 如果你的程序这一权利,导引头会左右摆动X = 0,超调每次。
  2. 相同的,但目标是静止的某处大于x = 0其它。 只要x相对的,不是绝对的(即,失主关心x中的差异 ,而不是目标的x)。
  3. 现在的目标是移动(或跳跃)。 导引头应该能够遵循它周围。 振荡将增大或缩小取决于如何在目标移动 - 你会明白我的意思。
  4. 现在两个维度。 导引头总是直接刺击向目标,这意味着你必须通过简单的触发除以推力为x和y分量。 如果移动目标,导引头可以进入它周围的轨道。
  5. 返回一个维度和一个固定的目标,但现在的导引头正试图交会,而不是一个飞越。 这是最困难的部分。 该目标是有距离和速度变为零的同时,没有过冲,因此失主必须知道它自己的制动能力。 当x小于比V ^ 2 / 2A,导引头必须反推,以减缓和适应它推离目标 。 这是很好的让求职者停止突刺时,这是非常接近目标。
  6. 目标再次开始转动。 这是容易的; 只是让x和相对V,不是绝对的。
  7. 多个尺寸。 这是非常容易; 在x,y和z部分是独立的。

现在,如果你想围绕一个导引头无法打开一毛钱,但必须曲线 ,事情变得棘手...

只是有几个三分球得到这个权利和容易。 1)这是最简单,最常用的有载体的工作,而这一切都写入两次或三次。 2)事情会看的权利,如果你控制的力量(这是有效的,因为A = F /质量的加速度),然后动态发展的速度和位置。

您的基本回路,逼真的动作看起来像(其中盖板是矢量和DT是你的时间步长):

while (motion) {
A = get_acceleration(X, V, A, X_target, V_targer, A_target)
V += A*dt // V is the integral of A
X += V*dt // X is the integral of V
}

真的,这是它为你动态演变。

然后,你需要决定如何确定的加速度,即写get_acceleration 有许多在这里选择依赖于多种因素,和现实生活中的猎采用多个策略。 例如,如果你有很多相对的推力给你的质量(即高加速度),你可能只是想直奔在目标; 但如果你有很多肿块相对于你的推力,你可能想使拦截过程。 如果你想,当你接近目标减速,你可以扭转加速度时|X-X_target|变小(即他们亲近)和/或它们的速度接近。 另外,阻尼可以帮助事情不振荡,而对于这一点,术语添加到加速度类似-c*(V-V_target) 我建议你​​玩这些,直到你得到的东西相匹配的物理外观和感觉,你的目标的。

分类:数学 时间:2015-03-14 人气:0
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.443 (s). 10 q(s)