poj 1410 Intersection(矩形和线段交)

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

poj 1410 Intersection(矩形和线段交)_第1张图片 

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

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

#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;
}


你可能感兴趣的:(poj 1410 Intersection(矩形和线段交))