判断两线段是否相交
Posted with-penguin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了判断两线段是否相交相关的知识,希望对你有一定的参考价值。
给定两线段 (P_1P_2) 和 (P_3P_4),要求判断他们是否相交。
通过两个步骤完成判断:
- 快速排斥实验。如果两个线段相交,那么分别以这两个线段为对角线的矩形一定相交(包括只有公共边或只有公共点的相交)。我们首先判断这两个线段是否满足这个条件。
- 跨立实验。如果这两个线段幸运的通过了上面那个实验,那么将接着接受跨立实验的考验。如果把其中一个线段看做矢量,那么另外一个线段的两个端点必然分别在这个矢量的左右两侧。我们分别把这两个线段当做矢量判断一次,如果都成立,那么这两个线段必有交点。
其实还有一些特殊的情况(例如两线段的叉积为 (0)),但是通过对特殊情况的枚举我们发现这两个实验可以正确的验证所有的情况,这也许就是这两个实验的妙处所在吧。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const double eps=1e-10;
struct Point
{
double x,y;
Point () {}
Point (double X,double Y) : x(X),y(Y) {}
Point operator - (const Point a) { return Point(x-a.x,y-a.y); }
double operator * (const Point a) { return x*a.y-y*a.x; }
void read() { scanf("%lf %lf",&x,&y); }
}P1,P2,P3,P4;
void init()
{
P1.read(),P2.read(),P3.read(),P4.read();
}
bool Both_Point(Point P1,Point P2,Point P3,Point P4)
{
if(!(max(P1.x,P2.x)+eps>=min(P3.x,P4.x)&&min(P1.x,P2.x)<=max(P3.x,P4.x)+eps))
return 0;
if(!(max(P1.y,P2.y)+eps>=min(P3.y,P4.y)&&min(P1.y,P2.y)<=max(P3.y,P4.y)+eps))
return 0;
if(((P2-P1)*(P3-P1))*((P2-P1)*(P4-P1))>eps)
return 0;
if(((P4-P3)*(P1-P3))*((P4-P3)*(P2-P3))>eps)
return 0;
return 1;
}
void work()
{
if(Both_Point(P1,P2,P3,P4))
puts("YES");
else
puts("NO");
}
int main()
{
init();
work();
return 0;
}
以上是关于判断两线段是否相交的主要内容,如果未能解决你的问题,请参考以下文章