鉴于:
在时间0,目标位于A点,拦截器位于B点.在未来的某个时刻,它们将在C点相交.
线段a与点A相对,同样对于b和B,以及c和C.

我们知道A和B的位置.我们可以从目标的航向得出角度CAB.我们知道线段a和b的长度比等于(interceptor.speed/target.speed).
首先,找到角度CAB.
设矢量B ^等于目标的速度.
设矢量C ^等于(interceptor.position.x - target.position.x,interceptor.position.y - target.position.y).
使用点积公式确定它们之间的角度.
B dot C = ||B|| * ||C|| * cos(angle)
cos(angle) = (B dot C) / (||B|| * ||C||)
angle = arccos((B dot C) / (||B|| * ||C||))
Run Code Online (Sandbox Code Playgroud)
..."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 using T = b / target.speed和C using C = target.position + (target.velocity * T).
我的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
Run Code Online (Sandbox Code Playgroud)
位置和时间与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;
}
Run Code Online (Sandbox Code Playgroud)
您可以使用2D矢量计算计算交点.目标沿着一条线移动.我们知道目标的起点,方向和速度.
在任何时候t> = 0,目标位于由x定义的点x处

其中s_t是目标(120,40)的起始点,v_t是目标(5,2)的速度矢量.
我们知道拦截器的起点(s_i),它的速度(v_i),但不知道它的方向.我们可以用起点周围的圆来描述拦截器的范围,其半径随时间增加.在矢量微积分中,我们得到了

其中x是圆上的点,s_i是拦截器(80,80)的起点,r是拦截器在时间t的半径(或范围),v_i是拦截器(10)的速度.
当目标和拦截器在时间t相遇时,它们的位置x必须相等.我们在圆周方程的x中使用线方程的x得到

这只是t 的正规二次方程:

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