思路:先判断是否在矩形内部,再判断线段是否能和矩形的某条边相交,若满足其中一个条件则为真,否则为假。
discuss中有人说给的点不是按左上和右下的顺序,如果对每条边都判断的话就不用考虑左上角或者右下角了,代码如下:
#include<stdio.h>
#include<iostream>
using namespace std;
struct Point{
int x,y;
};
int Mul(Point p1,Point p2,Point p)
{
return ((p1.x-p.x)*(p2.y-p.y)-(p2.x-p.x)*(p1.y-p.y));
}
bool iscross(Point p1,Point p2,Point p3,Point p4) //判断是否两条线段相交
{
return ((max(p1.x,p2.x)>=min(p3.x,p4.x)) && (min(p1.x,p2.x)<=max(p3.x,p4.x)) && (max(p1.y,p2.y)>=min(p3.y,p4.y)) && (min(p1.y,p2.y)<=max(p3.y,p4.y)) && (Mul(p3,p2,p1)*Mul(p2,p4,p1)>=0) && (Mul(p1,p4,p3)*Mul(p4,p2,p3)>=0));
}
bool isIn(Point p1,Point p2,Point p3,Point p4) //判断是否在矩形内部
{
if(max(p1.x,p2.x)>max(p3.x,p4.x))
return false;
if(max(p1.y,p2.y)>max(p3.y,p4.y))
return false;
if(min(p1.x,p2.x)<min(p3.x,p4.x))
return false;
if(min(p1.y,p2.y)<min(p3.y,p4.y))
return false;
return true;
}
int main()
{
int t,i;
Point s,e,r[4];
scanf("%d",&t);
while(t--)
{
bool flag=0;
scanf("%d %d %d %d",&s.x,&s.y,&e.x,&e.y);
scanf("%d %d %d %d",&r[0].x,&r[0].y,&r[2].x,&r[2].y);
r[1].x=r[0].x;
r[1].y=r[2].y;
r[3].x=r[2].x;
r[3].y=r[0].y;
if(isIn(s,e,r[0],r[2]))
flag=1;
for(i=0;i<4;i++)//对每条边都判断
if(iscross(s,e,r[i],r[(i+1)%4]))
flag=1;
if(flag)
printf("T\n");
else
printf("F\n");
}
return 0;
}