C# 截取向量的计算

C# 截取向量的计算,c#,math,vector,C#,Math,Vector,我有两个对象(我将它们称为目标和拦截器)。 我知道目标的当前位置和速度。 我知道拦截器的当前位置和速度 因此,我现在需要知道的是: 是否可能在同一时间点的同一位置进行拦截 拦截器需要在什么载体上飞行 拦截需要多长时间 i、 e目标(120,40)速度为每秒5,2秒,拦截器(80,80)速度为每秒10秒 我环顾四周,找到了很多方法来找出它们相遇的点,它们都围绕着两个向量之间的角度旋转,因为我不知道第二个向量,我无法计算,我在尝试解决这个问题时迷失了方向 对于如何进行的任何建议或指导,我们将不胜

我有两个对象(我将它们称为目标拦截器)。 我知道目标的当前位置和速度。 我知道拦截器的当前位置和速度

因此,我现在需要知道的是:

  • 是否可能在同一时间点的同一位置进行拦截
  • 拦截器需要在什么载体上飞行
  • 拦截需要多长时间
i、 e目标(120,40)速度为每秒5,2秒,拦截器(80,80)速度为每秒10秒

我环顾四周,找到了很多方法来找出它们相遇的点,它们都围绕着两个向量之间的角度旋转,因为我不知道第二个向量,我无法计算,我在尝试解决这个问题时迷失了方向

对于如何进行的任何建议或指导,我们将不胜感激。

给出:

时间0时,目标在A点,拦截器在B点。在将来的某个点,它们将在C点相交

线段a与点a相对,同样,对于b和b以及c和c也是如此


我们知道A和B的位置。我们可以从目标的航向推导出驾驶室的角度。我们知道线段a和b的长度之比等于(interceptor.speed/target.speed)

首先,找到角驾驶室。
让向量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||))
…其中“dot”是向量,而| | B | |是向量B的标量大小。
angle
是角度CAB

现在我们将找到角度ABC。
使用,我们知道
sin(ABC)/b==sin(CAB)/a
。 将方程重新排列为
ABC=arcin(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版本


可以使用二维矢量计算来计算交点。目标沿着一条线移动。我们知道目标的起点、方向和速度

在任何时间t>=0时,目标位于由定义的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


既然知道了t,就可以用第一条直线方程计算交点了。目标和拦截器在(163.065,57.223)处相遇

我相信你也想知道拦截器的速度矢量,否则你无法计算……速度就是速度和方向,我已经知道速度,所以一旦我有了表示方向的矢量,我就有了速度,一旦你有了截距点,你就可以计算出向量移动的距离。所以到达截距点所需的时间是t=s/v。假设两个向量的开始时间相同。那么t1和t2应该相等。@jdweng:我找到的所有东西都需要向量来计算拦截点,我知道拦截点的位置+速度*时间=目标位置+速度*时间,其中每个位置的时间相同。但是当我不知道时间的时候,我正试图重新安排方程式来计算拦截器的速度,我迷失了方向。咨询Thamls Kevin只是想让我的头脑回到代数上来。现在我不确定如何100%地判断拦截器是否可能。我怀疑1)arccos会失败,因为参数超出范围;2) ARCIN将因同样的原因失败;或3)C的所有可能位置将有负碰撞时间。@Kevin失败的是arcsin,“某些原因”是数量
sin(CAB)*b/a
大于1(或小于-1)。arccos可能会失败,但这只是由于舍入误差(对于几乎共线的B^和C^)。@Kevin,我想我必须向gdir给出答案,我认为你们都是对的,但他的解决方案对于其他尝试这样做的人来说更容易理解。谢谢你的帮助,尽管这是错误的。它根本不使用线性代数向量;这个答案使用了一种更慢的trig方法。我喜欢这个答案。您还可以注意到,在某些情况下,拦截器无法捕获目标-当二次型中的线性项为
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;
}