【问题标题】:Calculating Intercepting Vector计算拦截向量
【发布时间】:2015-04-29 21:10:46
【问题描述】:

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

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

  • 是否可以拦截,即同一时间点的同一地点。
  • 拦截器需要在哪个向量上行驶
  • 拦截需要多长时间

即目标 @ (120,40) 每秒 V(5,2) 和拦截器 @ (80,80) 可以每秒 10 的速度行进。

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

对于如何进行的任何建议或指导表示赞赏。

【问题讨论】:

  • 相信你也想知道拦截器的速度矢量,否则你就没法计算了……
  • 速度是有方向的速度,我已经知道速度,所以一旦我有了表示方向的向量,我就会有速度,
  • 一旦你有了截点,你就可以计算出向量行进的距离。所以到达截点所需的时间是 t = s/v。假设两个向量的开始时间相同。那么 t1 和 t2 应该相等。
  • @jdweng:我发现的所有东西都需要向量来计算拦截点,我知道拦截器位置 + 速度 * 时间 = 目标位置 + 速度 * 时间每个时间都是相同的。但是当我不知道时间时,我在尝试重新排列方程式以找到拦截器速度时迷路了

标签: c# math vector


【解决方案1】:

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

在任何时间 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,得到

这只是一个普通的quadratic equation t:

您可以轻松解决此问题。在这种情况下,您会得到一个有效和无效的解决方案:

t1 = -5.2328 => 无效,因为 t 必须 >= 0

t2 = 8.61307

现在您知道了 t,您可以计算与第一行方程的交点。目标和拦截器在 (163.065, 57.223) 相遇

【讨论】:

  • 我喜欢这个答案。您还可以注意到,在某些情况下拦截器无法捕获目标 - 当您的二次方没有实根 == 当二次方中的线性项(通常为 b^2)小于 4 时,就会发生这种情况* 平方项 * 常数项 (4*a*c)。我知道 Q 中的示例不是这种情况,但总的来说它可能会发生
  • 快速实现我自己的答案,我也在 8.6 时得到 (163, 57) 所以我们要么是对的,要么都是错的:-D
  • 只是想仔细检查变量上方的箭头表示什么
  • @MikeT:上面有箭头的变量是vectors,没有箭头的变量是实数。
  • @gdir 谢谢关于我的想法,但不是 100% 它不是表示归一化向量,确实让我很困惑,直到我意识到你使用点符号表示不乘点积
【解决方案2】:

给定:

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

线段a与A点相对,b与B、c与C亦然。


我们知道 A 和 B 的位置。我们可以从目标的航向推导出角度 CAB。我们知道线段ab的长度之比等于(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||))

...其中“点”是dot product,而||B||是向量 B 的标量大小。angle 是角度 CAB。

现在我们将找到角 ABC。
使用law of sines,我们知道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# 有点生疏,所以 here 是一个示例 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;
}

【讨论】:

  • Thamls Kevin 现在只是想了解一下代数
  • 我不能 100% 确定如何判断拦截是否可行。我怀疑 1) arccos 将失败,因为参数超出范围; 2) arcsin 会因为同样的原因而失败;或 3) C 的所有可能位置都将具有负碰撞时间。
  • @Kevin 这将是 arcsin 将失败,“某种原因”将是数量 sin(CAB) * b / a 大于 1(或小于 -1)。 arccos 可能失败,但仅是由于舍入误差(对于几乎共线的 B^ 和 C^)。
  • @Kevin,我想我将不得不向 gdir 给出答案,我认为你的两个都是对的,但他的解决方案对于其他尝试这样做的人来说更容易阅读。谢谢你的帮助
  • 这是错误的。它根本不使用线性代数向量;这个答案使用的是一种慢 waaaaaaaaaay 的三角方法。
猜你喜欢
  • 2023-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-07
  • 2015-11-22
  • 2015-03-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多