计算拦截向量

5
我有两个物体(我将称它们为目标拦截器)。 我知道目标的当前位置和速度。 我知道拦截器的当前位置和其可行驶速度。
现在我需要知道的是:
  • 是否可以拦截,即相同时间在同一位置。
  • 拦截器需要沿着哪个向量移动?
  • 拦截需要多长时间?
例如,目标位于(120,40),速度为每秒V(5,2),而拦截器位于(80,80),其速度为每秒10。
我已经搜索了很多寻找它们相遇点的方法,但它们都围绕着两个向量之间的角度展开,而我不知道第二个向量,我也无法计算出来,并且我在尝试解决这个问题时感到迷茫。
对于如何继续进行是否有任何建议或指导?

我相信您也想知道拦截器速度向量,否则您将无法进行任何计算... - apomene
速度是带有方向的速度,我已经知道速度,所以一旦我有表示方向的向量,我就会得到速度。 - MikeT
2
请参考http://en.wikipedia.org/wiki/Circles_of_Apollonius#Apollonius_pursuit_problem。 - High Performance Mark
@Kevin 谢谢,我确定这是可能的,并且几乎确定答案需要从基本三角函数中生成一个同时方程。因为我可以计算出当前位置的向量,当与目标速度结合时,将使您能够计算出切线角度,这将给出矢量的大小,从而给出拦截器矢量的角度...但我一直在试图制定它时迷失了方向。 - MikeT
@HighPerformanceMark,我之前没有听说过阿波罗尼斯圆,看起来它可能是解决方案,但那篇简短的文章并没有提供太多细节。 - MikeT
显示剩余4条评论
2个回答

12
你可以使用二维向量计算来计算交点。目标沿着一条直线移动。我们知道目标的起始点、方向和速度。
在任何时间t >= 0,目标所在的点x由以下公式定义:

enter image description here

其中s_t是目标的起始点(120, 40),v_t是目标的速度向量(5,2)。

我们知道拦截器的起始点(s_i),其速度(v_i),但不知道其方向。 我们可以通过以起始点为中心的圆来描述拦截器的范围,其半径随时间增加而增加。 在向量微积分中,我们得到

enter image description here

其中,x是圆上的一个点,s_i是拦截器的起始点(80, 80),r是拦截器在时间t时的半径(或范围),v_i是拦截器的速度(10)。

当目标和拦截器在时间t相遇时,它们的位置x必须相等。我们将线性方程中的x代入圆形方程中得到:

enter image description here

那只是一个关于 t 的普通的二次方程

enter image description here

你可以轻松解决这个问题。在这种情况下,你会得到一个有效的和一个无效的解决方案:
t1 = -5.2328 => 无效,因为t必须>=0
t2 = 8.61307
现在你知道了t,你可以计算第一条线方程的交点。目标和拦截器在(163.065,57.223)相遇。

2
我喜欢这个答案。你还可以注意到,有些情况下拦截器无法捕捉目标 - 当你的二次方程没有实根时会发生这种情况 == 当二次方程中的线性项平方(通常为b ^ 2)小于4 * 平方项 * 常数项(4 * a * c)。我知道这不是问题Q中的情况,但一般情况下可能会发生。 - J Richard Snape
1
快速实现我的答案后,我在时间8.6处也得到了(163, 57)。所以我们要么都对,要么都错 :-D - Kevin
只是想确认一下变量上方的箭头表示什么。 - MikeT
@MikeT:带有箭头的变量是向量,没有箭头的变量是实数。 - gdir
@gdir 谢谢,这正是我所想的,但我并不确定它是否表示一个标准化向量,直到我意识到你使用点符号表示乘法而不是点积时,我感到相当困惑。 - MikeT
显示剩余2条评论

7
给定:
时间0,目标在点A,拦截器在点B。在未来的某个时间点,它们将在点C相交。
线段a位于点A的对面,同理b和B,c和C。
我们已知A和B的位置。我们可以从目标的航向推导出角度CAB。我们知道线段a和线段b的长度比为(拦截器速度/目标速度)。
首先,找到角度CAB。 让向量B ^等于目标的速度。 让向量C ^等于(拦截器位置.x-目标位置.x,拦截器位置.y-目标位置.y)。 使用点积公式确定它们之间的角度。
B dot C = ||B|| * ||C|| * cos(angle)
cos(angle) = (B dot C) / (||B|| * ||C||)
angle = arccos((B dot C) / (||B|| * ||C||))

在这里,“dot”是点积,||B||是向量B的标量大小。角度angle为CAB角。

现在我们来找到角度ABC。
使用正弦定律,我们知道sin(ABC) / b == sin(CAB) / a。 将方程重排成ABC = arcsin( sin(CAB) * (b/a) )
我们在上一步找到了CAB,我们知道b/a为target.speed/interceptor.speed,所以将这些值代入并找到ABC。

现在你知道了两个角度和两个点,应该能够推导出C的位置。如果你使用度数,则角度ACB等于180 -(CAB + ABC),如果你使用弧度,则等于Pi -(CAB + ABC)。使用正弦定律确定边b和c的长度。现在可以用T = b / target.speed找到T,并用C = target.position + (target.velocity * T)找到C。


我的C#有点生疏,因此这里提供了一个Python示例实现。让我们插入你的样本值,结果是:

Collision pos: Point(163.065368246, 57.2261472985)
Time: 8.61307364926
Angle A: 113.198590514
Angle B: 29.6680851288
Angle C: 37.1333243575
a: 86.1307364926
b: 46.3828210973
c: 56.5685424949

位置和时间与gdir发现的相同,因此我非常有信心,我们两种方法都有效。

编辑:MikeT:C#版本

public static double Dot(Vector a, Vector b)
{
    return a.X * b.X + a.Y * b.Y;
}
public static double Magnitude(Vector vec)
{
    return Math.Sqrt(vec.X * vec.X + vec.Y * vec.Y);
}
public static double AngleBetween(Vector b, Vector c)
{
    return Math.Acos(Dot(b, c) / (Magnitude(b) * Magnitude(c)));
}

public static  Vector? Find_collision_point(Point target_pos, Vector target_vel, Point interceptor_pos, double interceptor_speed)
{
    var k = Magnitude(target_vel) / interceptor_speed;
    var distance_to_target = Magnitude(interceptor_pos - target_pos);

    var b_hat = target_vel;
    var c_hat = interceptor_pos - target_pos;

    var CAB = AngleBetween(b_hat, c_hat);
    var ABC = Math.Asin(Math.Sin(CAB) * k);
    var ACB = (Math.PI) - (CAB + ABC);

    var j = distance_to_target / Math.Sin(ACB);
    var a = j * Math.Sin(CAB);
    var b = j * Math.Sin(ABC);


    var time_to_collision = b / Magnitude(target_vel);
    var collision_pos = target_pos + (target_vel * time_to_collision);

    return interceptor_pos - collision_pos;
}

谢谢,Kevin。我现在只是试图理解代数。 - MikeT
我不确定如何确定是否可能进行拦截。我怀疑要么1)arccos会因为参数超出范围而失败;2)arcsin也会因为同样的原因而失败;或者3)C的所有可能位置都会有负的碰撞时间。 - Kevin
2
@Kevin,会失败的是arcsin函数,而“某些原因”是因为量sin(CAB) * b / a大于1(或小于-1)。arccos函数可能会失败,但仅由于舍入误差(对于几乎共线的B^和C^)。 - Kyle
@Kevin,我想我必须把答案给gdir,我认为你们两个都是对的,但他的解决方案对于其他试图做到这一点的人来说更容易阅读。谢谢你的帮助。 - MikeT
1
这是错误的。它根本没有使用线性代数向量;这个答案使用的是三角函数方法,速度慢得多。 - Nate Neuhaus
1
好的,那么“错误”是什么意思呢?如果OP没有禁止使用三角函数,并且结果是正确的,那有什么问题呢?我承认“这不是最好的方法” :-) 但这与“错误”相去甚远。 - Kevin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接