感谢大佬的代码和讲解线段相交
题目
题目描述
平面直角坐标系中有一条线段 AB 和一条线段 CD ,求线段 CD 和线段 AB 的相交判断。
输入描述
第一行输入一个 T ,代表测试数据量
每组测试数据输入有两行,每行两个实数坐标 (x,y) 分别代表 A,B,C,D 四个点。
输出描述
若 AB 与 CD 规范相交, 输出 2
。
若 AB 与 CD 不规范相交, 输出 1
。
若 AB 与 CD 不相交, 输出 0
。
输入输出样例
示例 1
输入
3
6 2 3 4
4 5 2 2
7 7 10 1
7 7 3 9
1 6 3 5
2 5 1 4
输出
2
1
0
运行限制
- 最大运行时间:1s
- 最大运行内存: 256M
思路
我i们设定两个判定条件:
1.判定两条线段所在的最小矩形是否有重叠的部分:
这条判断标准的原理很简单,如果两条线段所在的最小矩形都没有重叠部分,那么两条线段就不可能相交,我们只需要比较线段的两个端点的x,y值就可以判定
2.通过叉乘判断A,B,C,D四个点的相对位置,这里是叉乘的解释定义
我们发现,当我们在判断c,d是否在ab两端时,如果ca和ab的叉乘与da和ab的叉乘符号相反,就说明c,d在ab的两端。我们判断ab是否在cd两端时也是用同样的思路。只有ab和cd都在对方的两端时,才说明两个线段相交。
规范相交:线段的端点不在另一条线段上
不规范相交:线段的端点在另一条线段上
本题要求我们求规范和不规范相交,我们只需要稍微改一下判定条件
代码1
class point(): #定义类
def __init__(self,x,y):
self.x=x
self.y=y
def cross(p1,p2,p3):
#跨立实验,先求向量p1p2和向量p1p3,再求他们的叉乘
x1=p2.x-p1.x
y1=p2.y-p1.y
x2=p3.x-p1.x
y2=p3.y-p1.y
return x1*y2-x2*y1
def IsIntersec(p1,p2,p3,p4): #判断两线段是否相交
#快速排斥,以l1、l2为对角线的矩形必相交,否则两线段不相交
if(max(p1.x,p2.x)>=min(p3.x,p4.x) #矩形1最右端大于矩形2最左端
and max(p3.x,p4.x)>=min(p1.x,p2.x) #矩形2最右端大于矩形最左端
and max(p1.y,p2.y)>=min(p3.y,p4.y) #矩形1最高端大于矩形最低端
and max(p3.y,p4.y)>=min(p1.y,p2.y)): #矩形2最高端大于矩形最低端
#若通过快速排斥则进行跨立实验
if(cross(p1,p2,p3)*cross(p1,p2,p4)<0
and cross(p3,p4,p1)*cross(p3,p4,p2)<0):
D=2
elif (cross(p1,p2,p3)*cross(p1,p2,p4)==0
and cross(p3,p4,p1)*cross(p3,p4,p2)==0):
D=1
else:
D=0
return D
t=int(input())
for i in range(t):
p1,p2,p3,p4=point(0,0),point(0,0),point(0,0),point(0,0)
x=list(map(float,input().split()))
y=list(map(float,input().split()))
p1.x,p1.y=x[0],x[1]
p2.x,p2.y=x[2],x[3]
p3.x,p3.y=y[0],y[1]
p4.x,p4.y=y[2],y[3]
print(IsIntersec(p1,p2,p3,p4))
代码2
通过元组输入数据,有些难懂,思路和代码1一样,仅作参考
def Cross(a,b,c):
return (c[1]-a[1])*(b[0]-a[0])-(c[0]-a[0])*(b[1]-a[1])
def intersection(a,b,c,d):
if max(a[0],b[0])<min(c[0],d[0]) or max(a[1],b[1])<min(c[1],d[1])\
or min(a[0],b[0])>max(c[0],d[0]) or min(a[1],b[1])>max(c[1],d[1]):
print(0)
return
#print(Cross(a,b,c)*Cross(a,b,d))
#print(Cross(c,d,a)*Cross(c,d,b))
if Cross(a,b,c)*Cross(a,b,d)>0 or Cross(c,d,a)*Cross(c,d,b)>0:
print(0)
return
if Cross(a,b,c)*Cross(a,b,d)==0:
print(1)
return
print(2)
return
t=int(input())
for i in range(t):
x=list(map(float,input().split()))
y=list(map(float,input().split()))
a,b=list((x[0],x[1])),list((x[2],x[3]))
c,d=list((y[0],y[1])),list((y[2],y[3]))
intersection(a,b,c,d)