判断线段是否相交

简介: 判断线段是否相交

感谢大佬的代码和讲解线段相交


题目

题目描述


平面直角坐标系中有一条线段 AB 和一条线段 CD ,求线段 CD 和线段 AB 的相交判断。


输入描述


第一行输入一个 T ,代表测试数据量

每组测试数据输入有两行,每行两个实数坐标 (x,y) 分别代表 A,B,C,D 四个点。


输出描述


若 AB 与 CD 规范相交, 输出 2

若 AB 与 CD 不规范相交, 输出 1

若 AB 与 CD 不相交, 输出 0


输入输出样例


示例 1

输入

1. 3
2. 6 2 3 4
3. 4 5 2 2
4. 7 7 10 1
5. 7 7 3 9
6. 1 6 3 5
7. 2 5 1 4

输出

1. 2
2. 1
3. 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


1. class point(): #定义类
2.     def __init__(self,x,y):
3. self.x=x
4. self.y=y   
5. 
6. def cross(p1,p2,p3):
7.     #跨立实验,先求向量p1p2和向量p1p3,再求他们的叉乘
8.     x1=p2.x-p1.x
9.     y1=p2.y-p1.y
10.     x2=p3.x-p1.x
11.     y2=p3.y-p1.y
12. return x1*y2-x2*y1
13. 
14. def IsIntersec(p1,p2,p3,p4): #判断两线段是否相交
15. 
16.     #快速排斥,以l1、l2为对角线的矩形必相交,否则两线段不相交
17. if(max(p1.x,p2.x)>=min(p3.x,p4.x)    #矩形1最右端大于矩形2最左端
18. and max(p3.x,p4.x)>=min(p1.x,p2.x)   #矩形2最右端大于矩形最左端
19. and max(p1.y,p2.y)>=min(p3.y,p4.y)   #矩形1最高端大于矩形最低端
20. and max(p3.y,p4.y)>=min(p1.y,p2.y)): #矩形2最高端大于矩形最低端
21. 
22.     #若通过快速排斥则进行跨立实验
23. if(cross(p1,p2,p3)*cross(p1,p2,p4)<0
24. and cross(p3,p4,p1)*cross(p3,p4,p2)<0):
25.             D=2
26.         elif (cross(p1,p2,p3)*cross(p1,p2,p4)==0
27. and cross(p3,p4,p1)*cross(p3,p4,p2)==0):
28.             D=1
29. else:
30.             D=0
31. return D
32. 
33. t=int(input())
34. for i in range(t):
35.     p1,p2,p3,p4=point(0,0),point(0,0),point(0,0),point(0,0)
36.     x=list(map(float,input().split()))
37.     y=list(map(float,input().split()))
38.     p1.x,p1.y=x[0],x[1]
39.     p2.x,p2.y=x[2],x[3]
40.     p3.x,p3.y=y[0],y[1]
41.     p4.x,p4.y=y[2],y[3]
42.     print(IsIntersec(p1,p2,p3,p4))


代码2


通过元组输入数据,有些难懂,思路和代码1一样,仅作参考

1. 
2. def Cross(a,b,c):
3. return (c[1]-a[1])*(b[0]-a[0])-(c[0]-a[0])*(b[1]-a[1])
4. 
5. 
6. def intersection(a,b,c,d):
7. if max(a[0],b[0])<min(c[0],d[0]) or max(a[1],b[1])<min(c[1],d[1])\
8. or min(a[0],b[0])>max(c[0],d[0]) or min(a[1],b[1])>max(c[1],d[1]):
9.         print(0)
10. return
11.     #print(Cross(a,b,c)*Cross(a,b,d))
12.     #print(Cross(c,d,a)*Cross(c,d,b))
13. if Cross(a,b,c)*Cross(a,b,d)>0 or Cross(c,d,a)*Cross(c,d,b)>0:
14.         print(0)
15. return
16. if Cross(a,b,c)*Cross(a,b,d)==0:
17.         print(1)
18. return
19.     print(2)
20. return
21. 
22. t=int(input())
23. for i in range(t):
24.     x=list(map(float,input().split()))
25.     y=list(map(float,input().split()))
26.     a,b=list((x[0],x[1])),list((x[2],x[3]))
27.     c,d=list((y[0],y[1])),list((y[2],y[3]))
28.     intersection(a,b,c,d)
目录
相关文章
|
6月前
|
算法 C++
平面中判断线段与矩形是否相交
平面中判断线段与矩形是否相交
92 0
|
9月前
|
人工智能 BI
最大不相交区间
最大不相交区间
判断两个链表是否相交,相交的话返回相交的节点
1.判断是否相交 找到两个链表的最后一个节点,看是否相同,相同的话就相交,反之. 2.找两个链表长度的差值 为什么要找两个链表的差值呢? 为了判断哪个长,以便让长的链表先走差值,方便找相交处 3.找相交处 长的走后,再便利长的和短的一起走,以找到相交节点
53 0
三角形判断
三角形判断
98 0
判断点是否在线段上
判断点是否在线段上
182 0
给你n个线段,代表线段的左右端点,问最少删几条线段,使得剩下当中存在一个线段与所有剩下的所有线段都有交集
考虑枚举每一条线段,求以此线段与所有线段都有交集,需要删除的线段数。 那么对于此线段[L,R],右端点小于L的,与它无交集,需要全删掉。同理左端点大于R的线段,也需要都删掉。 那么剩下的问题,就是需要删几个了。
118 0
|
C++ 计算机视觉
判断一个点是否在RotatedRect中
openCV函数pointPolygonTest(): C++: double pointPolygonTest(InputArray contour, Point2f pt, bool measureDist) 用于判断一个点是否在轮廓中 当measureDist设置为true时,若返回值为正,表示点在轮廓内部,返回值为负,表示在轮廓外部,返回值为0,表示在轮廓上。
1693 0
平面上给定n条线段,找出一个点,使这个点到这n条线段的距离和最小。
题目:平面上给定n条线段,找出一个点,使这个点到这n条线段的距离和最小。 源码如下: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 ...
1123 0