poj 1410 Intersection(矩形和线段交)

来源:互联网 发布:淘宝运动鞋店铺排行榜 编辑:程序博客网 时间:2024/06/06 02:17

http://poj.org/problem?id=1410

 

题意:判断线段和矩形是否相交,顶点位置除外

枚举矩形的每条边,再判断线段是否在矩形的内部(注意矩形的坐标需要自己判断)

#include <iostream>#include <stdio.h>#include <cstring>#include <cmath>#include <queue>#include <algorithm>using namespace std;typedef long long LL;#define N 110000#define INF 0x3f3f3f3f#define met(a, b) memset (a, b, sizeof(a))const double EPS = 1e-8;struct point{    double x, y;};struct line{    point sa, en;}Line[N], Q;double xmult (point p1, point p2, point p0){///叉积    return (p1.x-p0.x)*(p2.y-p0.y) - (p2.x-p0.x)*(p1.y-p0.y);}int Intersect_in (point s1, point e1, point s2, point e2)///判断线段是否相交{    if ((xmult(s1, s2, e1)*xmult(s1, e2, e1) >EPS ||        xmult(s2, s1, e2)*xmult(s2, e1, e2) > EPS))            return 0;///同侧    if (fabs(xmult(s1, s2, e1))<EPS&&fabs(xmult(s1, e2, e1))<EPS &&        fabs (xmult(s2, s1, e2))<EPS && fabs(xmult(s2, e1, e2)<EPS))            return 1;///共线    return 2;}point Intersection (point s1, point e1, point s2, point e2){///求交点    point ret = s1;    double t = ((s1.x-s2.x)*(s2.y-e2.y)-(s1.y-s2.y)*(s2.x-e2.x))/                ((s1.x-e1.x)*(s2.y-e2.y)-(s1.y-e1.y)*(s2.x-e2.x));    ret.x += (e1.x-s1.x)*t;    ret.y += (e1.y-s1.y)*t;    return ret;}bool Solve (){    int flag = 0;    for (int i=0; i<=3; i++)    {        int t = Intersect_in (Line[i].sa, Line[i].en, Q.sa, Q.en);        if (t==2)        {///线段与矩形的边相交            point ret = Intersection (Line[i].sa, Line[i].en, Q.sa, Q.en);            if (i==0 || i==3)            if (ret.y>Line[i].sa.y && ret.y<Line[i].en.y)            {                flag = 1;                break;            }            if (i==1 || i==2)            if (ret.x>Line[i].sa.x && ret.x<Line[i].en.x)            {                flag = 1;                break;            }        }        if (t==1)        {            if (i==1 || i==2)            if ((Q.sa.x>Line[i].sa.x && Q.sa.x<Line[i].en.x) || (Q.en.x>Line[i].sa.x && Q.en.x<Line[i].en.x) ||                (Q.sa.x<=Line[i].sa.x && Q.en.x>=Line[i].en.x) ||                (Q.en.x<=Line[i].sa.x && Q.sa.x>=Line[i].en.x))                flag = 1;            if (i==0 || i==3)            if ((Q.sa.y>Line[i].sa.y && Q.sa.y<Line[i].en.y) || (Q.en.y>Line[i].sa.y && Q.en.y<Line[i].en.y) ||                (Q.sa.y<=Line[i].sa.y && Q.en.y>=Line[i].en.y) ||                (Q.en.y<=Line[i].sa.y && Q.sa.y>=Line[i].en.y))                flag = 1;        }    }    if ((Q.sa.x-Line[1].sa.x>EPS && Line[1].en.x-Q.sa.x>EPS &&        Q.sa.y-Line[0].sa.y>EPS && Line[0].en.y-Q.sa.y>EPS) ||        (Q.en.x-Line[1].sa.x>EPS && Line[1].en.x-Q.en.x>EPS &&        Q.en.y-Line[0].sa.y>EPS && Line[0].en.y-Q.en.y>EPS))            flag = 1;///线段至少一个端点在矩形的内部    if ((fabs(Q.sa.x-Line[0].en.x)<EPS && fabs(Q.sa.y-Line[0].en.y)<EPS &&        fabs(Q.en.x-Line[1].en.x)<EPS && fabs(Q.en.y-Line[1].en.y)<EPS) ||        (fabs(Q.sa.x-Line[0].sa.x)<EPS && fabs(Q.sa.y-Line[0].sa.y)<EPS &&        fabs(Q.en.x-Line[2].en.x)<EPS && fabs(Q.en.y-Line[2].en.y)<EPS))            flag = 1;///对角线    if (flag) return true;    return false;}int main (){    int t;    scanf ("%d", &t);    while (t--)    {        double xstart, ystart, xend, yend, xleft, ytop, xright, ybottom, x1, y1, x2, y2;        scanf ("%lf%lf%lf%lf%lf%lf%lf%lf", &xstart, &ystart, &xend, ¥d, &x1, &y1, &x2, &y2);        xleft = min (x1, x2);        xright = max (x1, x2);        ytop = max (y1, y2);        ybottom = min (y1, y2);        ///矩形的四条边        Line[0].sa.x = xleft, Line[0].sa.y = ybottom;        Line[0].en.x = xleft, Line[0].en.y = ytop;        Line[1].sa.x = xleft, Line[1].sa.y = ybottom;        Line[1].en.x = xright, Line[1].en.y = ybottom;        Line[2].sa.x = xleft, Line[2].sa.y = ytop;        Line[2].en.x = xright, Line[2].en.y = ytop;        Line[3].sa.x = xright, Line[3].sa.y = ybottom;        Line[3].en.x = xright, Line[3].en.y = ytop;        ///线段        Q.sa.x = xstart, Q.sa.y = ystart;        Q.en.x = xend, Q.en.y = yend;        if (xstart > xend)            swap (Q.sa, Q.en);        bool flag = Solve ();        if (flag) puts ("T");        else puts ("F");    }    return 0;}


0 0
原创粉丝点击