我正在尝试设计一个具有连续碰撞检测的2D物理引擎。对象存储为非旋转线段列表。因此,我可以通过查找任意两个对象之间的每对线段之间的碰撞时间来检测碰撞。
我想找到两个在恒定方向上移动的移动线段之间的交叉点的精确时间,并且证明是困难的。
我已经发现我可以通过找到线段上的每个点与另一个线段之间的冲突时间来进一步简化问题(反之亦然)。它可能在计算上效率低下,因此两个线段的通用解决方案将是理想的答案。我也可以忽略线条平行的情况(我想把一条线/点分享与'无碰撞'相同的位置和速度)。
如果答案“不可能”到完全找到此交叉时间,我会接受它作为解决方案。任何有关该主题的帮助将不胜感激。
编辑:根据维基百科关于Line segment的文章,对于包含端点A = (a_x, a_y)
和C = (c_x, c_y)
的线段,线段的一般公式看起来像这样:
对于线段 - 点交叉点,将替换为
p_x + p_v * t
代表a_x
(仅限左侧,右侧只有p_x
)p_y + p_v * t
代表a_y
(仅限左侧,右侧只有p_y
)q_x + q_v * t
代表c_x
(仅限左侧,右侧只有q_x
)q_y + q_v * t
代表c_y
(仅限左侧,右侧只有q_y
)r_x + r_v * t
x
{li> r_y + r_v * t
y
对于线段pq [(p_x, p_y), (q_x, q_y)]
,指向r (r_x, r_y)
,以p_v
== q_v
!= r_v
的速率移动可解决t?这是完整的等式:
答案 0 :(得分:1)
我上面的公式是不正确的,因为它对x和y组件使用相同的速度。
由于速度是常数,我可以简化方程,使得点相对于线段移动。通过使用v = r_v - qp_v
表示点r
的速度,使用0
表示每个线段的速度,用于速度的变量量会大大减少。插入变量的等式变为:
感谢WolframAlpha,然后为t:
求解方程
有趣的是,如果你分析它,它就是3D的对称。 [x1, y1, 0]
和[x2, y2, 0]
的交叉产品为[0, 0, x1*y2 - y1*x2]
。然后,这个等式转换为:
答案 1 :(得分:0)
对于线段 - 点交叉点,我可以找到存在碰撞的间隔(尽管此间隔大于碰撞的实际时间):
给定以[p, q]
移动的线段v
和速度为r
w
的点direction(w) != direction(v)
,定义三行{{1} }。让L1 = [p, p+v], L2 = [q, q+v], L3 = [r, r+w]
和t1, t_p
分别是t2, t_q
和L1
之间以及L3
和L2
之间的交叉时间。如果区间L3
与[t1, t2]
不相互排斥,则在这两个区间的交点中存在交叉点(例如[t_p, t_q]
和[-1, 10]
之间的交点为{{1 }})。如果这些间隔是互斥的,那么就没有碰撞。
此外,如果[2, 20]
和[2, 10]
的方向相同,但长度不相等,则可以找到确切的碰撞时间。投影到v
行时,w
为s
点。如果此点位于线段r
中,则会在[p, q]
处发生碰撞,可以通过将点[p, q]
和点t1
之间的距离除以点r
和线段s
之间的相对速度。
使用间隔可以通过使用二元搜索来比较特定时间段和点之间的距离来估算时间。然而,这是非常低效的。