我创建了这段代码来查找python中2个线段之间的交叉点,但它似乎并没有为所有行生成正确的结果:
注意:我在游戏中使用它,y值随着你的下降而增加。左上角是(0,0),左下角是(0,300)。不确定这是否有所作为。
def getIntersectPoint(p1, p2, p3, p4):
e = sys.float_info.epsilon * 1000
# reorganize points from smaller to bigger in x-axis
if p2[0]<p1[0]:
p1,p2=p2,p1
if p4[0]<p3[0]:
p3,p4=p4,p3
rise1 = float(p2[1]-p1[1])
run1 = float(p2[0]-p1[0])
if abs(run1) <= e:
m1 = None
b1 = float(p1[0])
else:
m1 = rise1/run1
b1 = float(p1[1]-m1*p1[0])
rise2 = float(p4[1]-p3[1])
run2 = float(p4[0]-p3[0])
if abs(run2) <= e:
m2 = None
b2 = float(p3[0])
else:
m2 = rise2/run2
b2 = float(p3[1]-m2*p3[0])
# check if lines are parallel
if (m1==None and m2==None) or (m1!=None and m2!=None and abs(m1-m2)<=e):
#check if they are right on top of each other
if abs(b1-b2)<=e:
return () # infinite points
return None
elif m1==None:
iy2 = m2*b1 + b2
ix, iy = b1, iy2
elif m2==None:
iy1 = m1*b2 + b1
ix, iy = b2, iy1
else:
ix = (b1-b2)/(m2-m1)
iy = m1*ix + b1
# check if the intersection is in the bounding box
if ix>=p1[0]-e and ix<=p2[0]+e and ix>=p3[0]-e and ix<=p4[0]+e:
if iy>=p1[1]-e and iy<=p2[1]+e and iy>=p3[1]-e and iy<=p4[1]+e:
return [ix, iy]
return None
在p1,p2,p3,p4格式中找不到交集时生成的一些测试用例:
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [440, 0] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [440, 0]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [0, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 280] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [440, 0] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [440, 0]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [0, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 280] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [440, 0] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [440, 0]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [0, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 280] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [440, 0] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [440, 0]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [0, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 280] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [440, 0] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [440, 0]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [0, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 280] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [440, 0] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [440, 0]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [0, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 280] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [440, 0] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [440, 0]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [0, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 280] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [440, 0] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [440, 0]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [0, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 280] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [440, 0] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [440, 0]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [0, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 280] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [440, 0] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [440, 0]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [0, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 280] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [440, 0] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [440, 0]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [0, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 280] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [440, 0] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [440, 0]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [0, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 280] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [440, 0] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [440, 0]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [0, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 280] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [440, 0] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [440, 0]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [0, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 280] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [440, 0] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [440, 0]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [0, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 280] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [440, 0] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [440, 0]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [0, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 280] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [440, 0] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [440, 0]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [0, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 280] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [440, 0] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [440, 0]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [0, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 280] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [440, 0] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [440, 0]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [0, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 280] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [440, 0] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [440, 0]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 0] [0, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [0, 280] [440, 280]
[-545.901858671, 443.161842698] [198.177615767, 149.315393477] [440, 0] [440, 280]
有谁知道错误是什么?
由于
答案 0 :(得分:0)
您遇到的问题是,您有时会根据其x值交换线段端点的顺序。但这也会改变y值的顺序,因此您对“边界框”内交叉点的测试失败。您可以尝试以下检查:
# check if the intersection is in the bounding box
if ix>=p1[0]-e and ix<=p2[0]+e and ix>=p3[0]-e and ix<=p4[0]+e:
y1, y2, y3, y4 = p1[1], p2[1], p3[1], p4[1]
if y2 < y1:
y2, y1 = y1, y2
if y4 < y3:
y4, y3 = y3, y4
if iy>=y1-e and iy<=y2+e and iy>=y3-e and iy<=y4+e:
return [ix, iy]