您的位置:首页 > 产品设计 > UI/UE

zoj 1648 Circuit Board (判断线段是否相交)

2014-08-04 21:01 375 查看
学习了算法导论上的线段相交的这部分!

正式进入计算几何的学习阶段~~~~~~

两条线段相交当且仅当下面两个条件至少成立一个:

1、每条线段都跨越了包含另一条线段的直线。

2、一条线段的某个端点落在另一条线段上。(这一情况来自与边界情况)

#include<cstdio>
#include<iostream>
#include<cstring>
#define maxn 2010

using namespace std;

struct Point
{
    double x,y;
}point[maxn<<1];

struct node
{
    Point a,b;
}seg[maxn];

double direction(Point a,Point b,Point c)
{
    double c1,c2,c3,c4;
    c1 = c.x-a.x;
    c2 = c.y-a.y;
    c3 = b.x-a.x;
    c4 = b.y-a.y;
    return (c1*c4-c2*c3);
}
bool onsegment(Point a,Point b,Point c)
{
    if(c.x<=max(a.x,b.x) && c.x>=min(a.x,b.x) && c.y<=max(a.y,b.y)&& c.y>=min(a.y,b.y))
        return true;
    else return false;
}
bool segintersect(int i,int j)
{
    Point a = seg[i].a;
    Point b = seg[i].b;
    Point c = seg[j].a;
    Point d = seg[j].b;
    double d1,d2,d3,d4;
    d1 = direction(a,b,c);
    d2 = direction(a,b,d);
    d3 = direction(c,d,a);
    d4 = direction(c,d,b);
    if(d1*d2<0 && d3*d4<0)
        return true;
    else if(d1==0 && onsegment(a,b,c))
        return true;
    else if(d2==0 && onsegment(a,b,d))
        return true;
    else if(d3==0 && onsegment(c,d,a))
        return true;
    else if(d4==0 && onsegment(c,d,b))
        return true;
    else return false;
}

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int c = 0;
        for(int i=0;i<n;i++)
        {
            scanf("%lf%lf%lf%lf",&point[c].x,&point[c++].y,&point[c].x,&point[c].y);
            seg[i].a = point[c-1];
            seg[i].b = point[c];
            c++;
        }
        int flag = 0;
        for(int i=0;i<n && !flag;i++)
        {
            for(int j=i+1;j<n;j++)
            {
                if(segintersect(i,j))
                {
                    flag = 1;
                    break;
                }
            }
        }
        if(!flag)
            puts("ok!");
        else puts("burned!");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: