如何用Python高效检测平面内两球的轨迹碰撞干扰?
二维球体直线运动碰撞检测实现方案
核心逻辑
两个半径均为r的球体,当球心距离≤2r时触发碰撞。要判断C球从C到P的直线运动是否会与T球碰撞,需完成两步判断:
- T球的碰撞范围是否与C球的运动线段CP相交
- 碰撞发生的位置是否在C球到达P点之前
用向量几何计算是高效的方案,避免了复杂的方程求解:
- 计算向量
CP(从C到P)和CT(从C到T) - 判断T球在CP线段上的投影点是否在线段范围内
- 计算T球到CP直线的最短距离,结合投影位置确认是否会发生碰撞
Python实现(基于numpy)
import numpy as np def detect_collision(C, T, P, r): # 转换为numpy数组简化向量运算 C = np.array(C, dtype=np.float64) T = np.array(T, dtype=np.float64) P = np.array(P, dtype=np.float64) vector_CP = P - C vector_CT = T - C cp_sq_length = np.dot(vector_CP, vector_CP) # 特殊情况:C与P重合,无运动 if cp_sq_length == 0: return np.linalg.norm(vector_CT) <= 2 * r # 计算投影系数t,t∈[0,1]表示投影点在线段CP上 t = np.dot(vector_CT, vector_CP) / cp_sq_length if t < 0 or t > 1: # 投影点在线段外,仅需判断两端点是否碰撞 dist_start = np.linalg.norm(vector_CT) dist_end = np.linalg.norm(T - P) return dist_start <= 2 * r or dist_end <= 2 * r else: # 计算CP线段上的投影点 projection_point = C + t * vector_CP # 计算T到CP直线的最短距离 shortest_dist = np.linalg.norm(T - projection_point) if shortest_dist <= 2 * r: # 验证碰撞发生时C球的位置是否在CP线段内 if shortest_dist == 0: collision_pos_C = projection_point else: direction = (projection_point - T) / shortest_dist collision_pos_C = projection_point + direction * (2 * r - shortest_dist) # 碰撞位置在C到P之间则返回True return np.dot(collision_pos_C - C, P - collision_pos_C) >= 0 return False # 测试给定配置 C = (389, 464) T = (253, 211) P = (115, 100) r = 60 print("碰撞检测结果:", detect_collision(C, T, P, r))
额外说明
- 若需结合Pygame可视化,可在检测到碰撞后,用
pygame.draw.line()绘制运动轨迹,pygame.draw.circle()绘制球体和碰撞点 - 关于蓝色区域的限制:只需在检测前添加坐标判断,比如蓝色区域是矩形
(x1,y1,x2,y2),则先判断x1 <= T[0] <= x2 and y1 <= T[1] <= y2,若不满足再执行碰撞检测 - 该方法基于向量运算,计算复杂度为O(1),适合实时检测场景
内容的提问来源于stack exchange,提问作者Optical_flow_lover
相关产品推荐
相关产品推荐

