You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

计算两个运动二维边界框的碰撞时间

二维恒定速度边界框碰撞时间计算

核心思路

把问题转化为相对运动分析:将其中一个边界框视为静止,另一个以相对速度运动,只需计算运动的边界框何时会与静止边界框的投影在x、y轴上同时重叠。

步骤1:定义基础参数

假设两个边界框为A和B:

  • 边界框A:初始中心坐标$(x_{A0}, y_{A0})$,半长/半宽$(w_A, h_A)$,速度$(v_{Ax}, v_{Ay})$
  • 边界框B:初始中心坐标$(x_{B0}, y_{B0})$,半长/半宽$(w_B, h_B)$,速度$(v_{Bx}, v_{By})$

先计算相对运动参数:

  • 相对速度:$\vec{v}{rel} = (v{Ax} - v_{Bx}, v_{Ay} - v_{By})$
  • 初始相对位移:$\vec{d}{rel0} = (x{A0} - x_{B0}, y_{A0} - y_{B0})$

步骤2:计算单轴重叠时间区间

碰撞的必要条件是x、y轴的投影区间同时重叠,分别计算两个轴的有效时间范围:

X轴方向

两个边界框的x轴投影重叠条件为:
$$-(w_A + w_B) \leq d_{rel0x} + v_{relx}t \leq w_A + w_B$$

分情况求解:

  • 若$v_{relx} = 0$:
    • 若$|d_{rel0x}| \leq w_A + w_B$,x轴始终重叠,时间区间为$[0, +\infty)$
    • 否则x轴永远不重叠,直接判定无碰撞
  • 若$v_{relx} \neq 0$:
    • 解不等式得到t的范围$[t_{x1}, t_{x2}]$(确保$t_{x1} \leq t_{x2}$)

Y轴方向

用完全相同的逻辑计算y轴的重叠时间区间$[t_{y1}, t_{y2}]$。

步骤3:求时间区间的交集

碰撞发生的时间t必须同时满足x、y轴的重叠条件,且$t \geq 0$(只考虑未来时刻):

  • 计算交集:$t_{start} = \max(t_{x1}, t_{y1}, 0)$,$t_{end} = \min(t_{x2}, t_{y2})$
  • 若$t_{start} \leq t_{end}$:$t_{start}$就是最早碰撞时间,$[t_{start}, t_{end}]$是碰撞持续时间段
  • 若交集为空:无碰撞

步骤4:特殊情况处理

  • 初始时刻(t=0)已碰撞:直接返回t=0
  • 相对速度为0($\vec{v}_{rel}=(0,0)$):初始重叠则持续碰撞,否则永不碰撞
  • 边界框相切:视为碰撞,取对应t值

示例代码片段(Python)

def get_collision_time(box_a, box_b):
    # box格式:(初始x, 初始y, 半宽, 半高, x方向速度, y方向速度)
    x_a0, y_a0, w_a, h_a, v_ax, v_ay = box_a
    x_b0, y_b0, w_b, h_b, v_bx, v_by = box_b

    # 计算相对位移和相对速度
    dx0 = x_a0 - x_b0
    dy0 = y_a0 - y_b0
    vx_rel = v_ax - v_bx
    vy_rel = v_ay - v_by

    # 计算单轴的有效时间区间
    def calc_axis_interval(d0, v_rel, sum_half):
        if v_rel == 0:
            if abs(d0) <= sum_half:
                return (0, float('inf'))
            else:
                return (float('inf'), -float('inf'))  # 空区间标记
        t1 = (-sum_half - d0) / v_rel
        t2 = (sum_half - d0) / v_rel
        return (min(t1, t2), max(t1, t2))

    tx1, tx2 = calc_axis_interval(dx0, vx_rel, w_a + w_b)
    ty1, ty2 = calc_axis_interval(dy0, vy_rel, h_a + h_b)

    # 求有效时间交集
    t_start = max(tx1, ty1, 0)
    t_end = min(tx2, ty2)

    return t_start if t_start <= t_end else None

# 测试用例
box1 = (0, 0, 1, 1, 1, 0)
box2 = (5, 0, 1, 1, 0, 0)
collision_t = get_collision_time(box1, box2)
print(f"最早碰撞时间: {collision_t}" if collision_t else "无碰撞")

内容的提问来源于stack exchange,提问作者curiouscupcake

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 02:01:28