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