基于Numpy实现批量线段相交计算与s/t值输出的优雅方案咨询
批量线段相交参数计算解决方案
场景说明
现有一条固定的道路线段,需要批量判断3万条位移线段与其的相交情况,并输出所有线段对应的相交参数s、t,组成(2, 30000)维度的结果矩阵用于后续计算。
基础数据定义
import numpy as np # 固定道路线段的两个端点 p1_road_test = np.array([1, 1]) # 道路线段端点1的x、y坐标 p2_road_test = np.array([2, 4]) # 道路线段端点2的x、y坐标 # 待检测线段的原点集合(每行对应x、y坐标,每列对应一个点) p_origin_test = np.matrix([(3, 5, 6), (1, 1, 2)]) # 待检测线段的位移后点集合,与原点集合同列坐标组成一条位移线段 p_moved_test = np.matrix([(1,3, 3), (3, 3, 2)])
向量化实现方案
利用numpy的广播机制替代循环逐列计算,所有运算都是逐元素并行执行,3万条线段的计算可以在毫秒级完成,最终直接输出目标维度的参数矩阵:
# 提取固定道路线段的基础参数 X1, Y1 = p1_road_test[0], p1_road_test[1] X2, Y2 = p2_road_test[0], p2_road_test[1] dx1 = X2 - X1 dy1 = Y2 - Y1 # 批量计算所有位移线段的对应参数 dx2 = p_moved_test[0, :] - p_origin_test[0, :] dy2 = p_moved_test[1, :] - p_origin_test[1, :] dx3 = X1 - p_origin_test[0, :] dy3 = Y1 - p_origin_test[1, :] # 逐元素计算行列式与s、t参数 det = dx1 * dy2 - dx2 * dy1 det1 = dx1 * dy3 - dx3 * dy1 det2 = dx2 * dy3 - dx3 * dy2 # 处理det为0的平行/共线场景,可根据业务需求修改填充值 det[det == 0] = np.nan s = det1 / det t = det2 / det # 拼接为目标维度(2, N)的结果矩阵 result = np.vstack([s, t]) # 可选:直接获取所有相交线段的索引 intersect_mask = (s >= 0) & (s <= 1) & (t >=0) & (t <=1) intersect_index = np.where(intersect_mask)[1]
结果验证
运行上述代码后得到的result矩阵与你循环输出的结果完全一致:
[[0.75 1.5 1.55555556] [0.5 1. 0.33333333]]
注意事项
- numpy.matrix已被官方标记为不推荐类型,你可以将输入转换为numpy.ndarray,代码逻辑不需要任何修改,运行效率会更高。
- 共线场景的特殊判断可以在det为0的分支里补充实现,不影响主体计算逻辑。
内容的提问来源于stack exchange,提问作者ohnoinkimono
相关产品推荐
相关产品推荐

