2D场景下已知点、方向向量及圆参数求解射线与圆周交点方法
问题背景
已知某点位于圆内部,如何计算该点沿指定方向向量运动后与圆周的交点?即已知圆心位置、半径、质点位置、运动速度向量,如何求解质点撞击圆周的具体坐标?
实际应用场景
当前正在开发航班雷达系统,所有航班数据存储在队列中,需要根据航班飞出雷达半径范围的剩余时长对队列排序。求得交点坐标后,即可通过两点间距结合运动速度计算对应的剩余时长,场景示意图如下:
求解方法
这是典型的二维射线与圆求交问题,因质点初始位置在圆内,只会存在1个沿运动方向的有效交点,推导过程如下:
已知参数定义
- 圆心坐标:$C(x_c, y_c)$
- 雷达半径:$R$
- 航班当前坐标:$P_0(x_0, y_0)$
- 航班速度向量:$\vec{v}(v_x, v_y)$(自带速率,无需单独拆分方向和速率)
公式推导
- 航班沿速度向量运动$t$时间后的坐标可表示为:
$P(t) = P_0 + t \times \vec{v}$,其中$t>0$ - 交点满足圆周方程,即到圆心距离等于半径:
$|P(t) - C|^2 = R^2$ - 展开后可得关于$t$的一元二次方程:$a t^2 + b t + c = 0$,三个系数分别为:
- $a = \vec{v} \cdot \vec{v} = v_x^2 + v_y^2$
- $b = 2 \times [\vec{v} \cdot (P_0 - C)] = 2 \times (v_x(x_0 - x_c) + v_y(y_0 - y_c))$
- $c = |P_0 - C|^2 - R^2 = (x_0 - x_c)^2 + (y_0 - y_c)^2 - R^2$
- 因航班初始位置在圆内,故$c<0$,方程必然存在一个正根和一个负根,负根对应反方向的无效交点,取正根即可:
$t = \frac{-b + \sqrt{b^2 - 4ac}}{2a}$ - 将$t$代入坐标公式即可得到交点坐标,同时$t$就是航班飞出雷达范围的剩余时长,可直接用于队列排序,无需额外计算距离换算时间。
代码实现示例(Python)
import math def calc_flight_exit_info(radar_center: tuple[float, float], radar_radius: float, plane_pos: tuple[float, float], plane_velocity: tuple[float, float]) -> tuple[float, tuple[float, float]]: """ 计算航班飞出雷达范围的剩余时长和交点坐标 :param radar_center: 雷达圆心坐标 (x, y) :param radar_radius: 雷达覆盖半径 :param plane_pos: 航班当前坐标 (x, y) :param plane_velocity: 航班速度向量 (vx, vy) :return: 剩余时长t, 交点坐标(intersect_x, intersect_y) """ dx0 = plane_pos[0] - radar_center[0] dy0 = plane_pos[1] - radar_center[1] a = plane_velocity[0] ** 2 + plane_velocity[1] ** 2 b = 2 * (plane_velocity[0] * dx0 + plane_velocity[1] * dy0) c = dx0 ** 2 + dy0 ** 2 - radar_radius ** 2 discriminant = b ** 2 - 4 * a * c sqrt_discriminant = math.sqrt(discriminant) # 取正根得到剩余时长 exit_time = (-b + sqrt_discriminant) / (2 * a) # 计算交点坐标 intersect_x = plane_pos[0] + exit_time * plane_velocity[0] intersect_y = plane_pos[1] + exit_time * plane_velocity[1] return exit_time, (intersect_x, intersect_y)
内容的提问来源于stack exchange,提问作者Olav Ausland
相关产品推荐
相关产品推荐

