Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 在三维运动目标上发射射弹(直线弹道)_Algorithm_3d_Linear Algebra - Fatal编程技术网

Algorithm 在三维运动目标上发射射弹(直线弹道)

Algorithm 在三维运动目标上发射射弹(直线弹道),algorithm,3d,linear-algebra,Algorithm,3d,Linear Algebra,我已经在谷歌上搜索了这个问题,但只找到了二维解或对我不起作用的公式(发现这个公式看起来不错,但似乎不正确) 我已提出: Vec3 cannonPos; Vec3 targetPos; Vec3 targetVelocityVec; float bulletSpeed; 我要找的是时间 targetPos+t*targetVelocityVec 是大炮瞄准和射击的交叉点 我在寻找一个简单、便宜的t公式(简单的意思是不要做很多不必要的向量空间变换等等) 谢谢 真正的问题是找出子弹在空间中与目标路

我已经在谷歌上搜索了这个问题,但只找到了二维解或对我不起作用的公式(发现这个公式看起来不错,但似乎不正确)

我已提出:

Vec3 cannonPos;
Vec3 targetPos;
Vec3 targetVelocityVec;
float bulletSpeed;
我要找的是时间

targetPos+t*targetVelocityVec
是大炮瞄准和射击的交叉点

我在寻找一个简单、便宜的t公式(简单的意思是不要做很多不必要的向量空间变换等等)


谢谢

真正的问题是找出子弹在空间中与目标路径相交的位置。子弹的速度是恒定的,所以在一定的时间内,无论我们朝哪个方向发射,它都会移动相同的距离。这意味着它在时间t之后的位置将始终位于球体上。这是一个丑陋的2d插图:

该球体可以用数学表示为:

(x-x_b0)^2 + (y-y_b0)^2 + (z-z_b0)^2 = (bulletSpeed * t)^2      (eq 1)
x_b0、y_b0和z_b0表示加农炮的位置。您可以通过使用问题中提供的方程求解该方程来计算时间t:

targetPos+t*targetVelocityVec                                   (eq 2)
(等式2)
是一个向量方程,可分解为三个单独的方程:

x = x_t0 + t * v_x
y = y_t0 + t * v_y
z = z_t0 + t * v_z
这三个方程式可插入
(等式1)

该方程仅包含已知变量,可求解t。通过将二次子表达式的常数部分指定给常数,我们可以简化计算:

c_1 = x_t0 - x_b0
c_2 = y_t0 - y_b0
c_3 = z_t0 - z_b0
(v_b = bulletSpeed)

(t * v_x + c_1)^2 + (t * v_y + c_2)^2 + (t * v_z + c_3)^2 = (v_b * t)^2
将其重新排列为标准的二次方程:

(v_x^2+v_y^2+v_z^2-v_b^2)t^2 + 2*(v_x*c_1+v_y*c_2+v_z*c_3)t + (c_1^2+c_2^2+c_3^2) = 0
这很容易用标准公式解决。它可能导致零、一或两个解决方案。零解(不计算复杂解)意味着子弹不可能到达目标。当目标轨迹与球体的边缘相交时,一种解决方案可能很少出现。两种解决方案将是最常见的场景。消极的解决方案意味着你不能击中目标,因为你需要把子弹射到过去。这些都是你必须检查的条件

当你解出这个方程时,你可以通过把它放回
(等式2)
来找到t的位置。在伪代码中:

# setup all needed variables
c_1 = x_t0 - x_b0
c_2 = y_t0 - y_b0
c_3 = z_t0 - z_b0
v_b = bulletSpeed
# ... and so on

a = v_x^2+v_y^2+v_z^2-v_b^2
b = 2*(v_x*c_1+v_y*c_2+v_z*c_3)
c = c_1^2+c_2^2+c_3^2

if b^2 < 4*a*c:
    # no real solutions
    raise error

p = -b/(2*a)
q = sqrt(b^2 - 4*a*c)/(2*a)

t1 = p-q
t2 = p+q

if t1 < 0 and t2 < 0:
    # no positive solutions, all possible trajectories are in the past
    raise error

# we want to hit it at the earliest possible time
if t1 > t2: t = t2
else: t = t1

# calculate point of collision
x = x_t0 + t * v_x
y = y_t0 + t * v_y
z = z_t0 + t * v_z
#设置所有需要的变量
c_1=x_t0-x_b0
c_2=y_t0-y_b0
c_3=z_t0-z_b0
v_b=速度
# ... 等等
a=v_x^2+v_y^2+v_z^2-v_b^2
b=2*(v_x*c_1+v_y*c_2+v_z*c_3)
c=c_1^2+c_2^2+c_3^2
如果b^2<4*a*c:
#没有真正的解决办法
提出错误
p=-b/(2*a)
q=sqrt(b^2-4*a*c)/(2*a)
t1=p-q
t2=p+q
如果t1<0且t2<0:
#没有积极的解决方案,所有可能的轨迹都在过去
提出错误
#我们想尽早完成
如果t1>t2:t=t2
其他:t=t1
#计算碰撞点
x=x_t0+t*v_x
y=y_t0+t*v_y
z=z_t0+t*v_z

从技术上讲,不是“在过去发射加农炮”,而是在负
t
的情况下发射加农炮到过去
如果t1*t2>0
:如果两种解决方案都是正的,则可能会发生这种情况,因此在没有实际检查符号(或者说明为什么t1和t2不能都是正的,如果不能)。如果t1<0和t2<0,我个人会使用
。@mokus,我不知道我在想什么。谢谢。我想你最近可能写了太多的根查找算法;)@EmilH-我理解代码的一般流程,但是你能更好地解释示例代码的方程式吗?比如数学上做了什么,为什么?我不太明白
a
b
c
p
q
变量是什么;而且,尽管我认为我已经解决了其余大部分问题,但也不太容易理解。考虑到抛射体沿着直线轨道飞行,这个问题就变得很无趣:-(
# setup all needed variables
c_1 = x_t0 - x_b0
c_2 = y_t0 - y_b0
c_3 = z_t0 - z_b0
v_b = bulletSpeed
# ... and so on

a = v_x^2+v_y^2+v_z^2-v_b^2
b = 2*(v_x*c_1+v_y*c_2+v_z*c_3)
c = c_1^2+c_2^2+c_3^2

if b^2 < 4*a*c:
    # no real solutions
    raise error

p = -b/(2*a)
q = sqrt(b^2 - 4*a*c)/(2*a)

t1 = p-q
t2 = p+q

if t1 < 0 and t2 < 0:
    # no positive solutions, all possible trajectories are in the past
    raise error

# we want to hit it at the earliest possible time
if t1 > t2: t = t2
else: t = t1

# calculate point of collision
x = x_t0 + t * v_x
y = y_t0 + t * v_y
z = z_t0 + t * v_z