【计算几何/线段相交】HRBUST 1559 线段相交

线段相交

Time Limit: 1000 MS Memory Limit: 10240 K

Description

给定线段P1P2(P1和P2是线段的两端点,且不重合)、P3P4(P3和P4是线段的两端点,且不重合),判断P1P2和P3P4是否相交。P1P2和P3P4相交,即指存在一个点P,它既落在P1P2上又落在P3P4上(含线段的端点)。

Input

输入数据有多组,第一行为测试数据的组数N,下面包括2N行,每组测试数据含2行,第一行为P1P2的坐标值,第二行为P3P4的坐标值,比如下面的数据

表示P1、P2、P3、P4的坐标分别为:P1(0,0),P2(1,1),P3(2,2),P4(3,3)

Output

判断每组数据中的线段P1P2和P3P4是否相交,如果相交输出YES,否则输出NO。每组数据输出占一行。

Sample Input

2
0 0 1 1
2 2 3 3
0 0 2 0
0 0 1 3

Sample Output

NO
YES

Hint

两线段相交分为“规范相交”和“非规范相交”。 “规范相交”指的是两条线段恰有唯一一个不是端点的公共点;而如果一条线段的一个端点在另一条线段上,或者两条线段部分重合,则视为“非规范相交”,本题是“非规范相交”。

定义点坐标类型时需用double

Source

2012级新生练习赛 3

Author

sunshine@Hrbust

题意

给你两个线段,判断是否相交

思路

线段相交定理运用
另一条线段的两个端点都在当前线段的顺时针和逆时针方向

坑点

这个是非范式相交,注意情况要考虑完全

AC代码

#include
using namespace std;
#define EPS 1e-10
class Point{
public:
    double x,y;
    Point(int x=0,int y=0):x(x),y(y){}
    Point operator + (Point a){return Point(x+a.x,y+a.y);}
    Point operator - (Point b){return Point(x-b.x,y-b.y);}
    double norm(void){return x*x + y*y;}
};

typedef Point Vector;

double cross(Vector a,Vector b)
{
    return a.x*b.y - a.y*b.x;
}

double dot(Vector a,Vector b)
{
    return a.x*b.x + a.y*b.y;
}

int ccw(Point p0,Point p1,Point p2)
{
    Vector a = p1 - p0;
    Vector b = p2 - p0;
    if(cross(a,b)<-EPS) return -1;
    if(cross(a,b)>EPS) return 1;
    if(dot(a,b)<-EPS) return 2;
    if(a.norm() < b.norm()) return -2;
    return 0;
}

bool isinter(Point a,Point b,Point c,Point d)
{
    if(ccw(a,b,c)*ccw(a,b,d)<=0&&ccw(c,d,a)*ccw(c,d,b)<=0) return true;
    return false;
}

void solve(void)
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        Point a,b,c,d;
        cin>>a.x>>a.y>>b.x>>b.y>>c.x>>c.y>>d.x>>d.y;
        if(isinter(a,b,c,d)) cout<<"YES"<else cout<<"NO"<int main(void)
{
    solve();
    return 0;
}



你可能感兴趣的:(计算几何,ACM)