判断线段与矩形相交有两种相交方式:
1)线段与矩形的四条边的其中一条至少有一个交点(X积判断
2)线段再矩形内(用坐标大小判断
十分钟一A一计算几何水题,感觉自己越来越棒了。
513KB,0MS
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const double eps = 1e-8;
int dcmp( double x )
{
if( fabs(x)<eps)
return 0;
return x < 0 ? -1: 1;
}
//================= 点结构 ===============
struct pnode
{
double x,y;
pnode( double a=0.0,double b=0.0):x(a),y(b){}
// X乘重载
double operator ^ (const pnode &b)const
{
return x*b.y - b.x*y;
}
pnode operator - ( const pnode &b)const
{
return pnode( x-b.x, y-b.y);
}
};
//================ 线结构 ==============
typedef pnode myvec;
struct pline
{
pnode st,ed;//st:起始点 ed:终点
myvec vec;//向量
pline(){}
pline(pnode a,pnode b):st(a),ed(b)
{
vec = pnode(b-a);
}
void readl()
{
scanf("%lf %lf %lf %lf",&st.x,&st.y,&ed.x,&ed.y);
}
};
double cross( pnode p0,pnode p1,pnode p2)
{
return (p1-p0) ^ (p2-p0);
}
pline seg;
pline rec[5];
double xl,yt,xr,yb;
void set_rec()
{
rec[0] = pline( pnode(xl,yb),pnode(xl,yt) );
rec[1] = pline( pnode(xl,yt),pnode(xr,yt) );
rec[2] = pline( pnode(xr,yt),pnode(xr,yb) );
rec[4] = pline( pnode(xr,yb),pnode(xl,yb) );
}
//线段是否与矩形四条边至少有一个交点
bool seg_inter_seg(pline a,pline b)
{
return
max( a.st.x, a.ed.x) >= min( b.st.x, b.ed.x)
&&
max( b.st.x, b.ed.x) >= min( a.st.x, a.ed.x)
&&
max( a.st.y, a.ed.y) >= min( b.st.y, b.ed.y)
&&
max( b.st.y, b.ed.y) >= min( a.st.y, a.ed.y)
&&//以上端点判断
dcmp(cross( a.st, a.ed, b.st ))*dcmp(cross( a.st, a.ed, b.ed ))<=0
&& dcmp(cross( b.st, b.ed, a.st ))*dcmp(cross( b.st, b.ed, a.ed ))<=0;
}
//线段是否再矩形内
bool seg_in_rec()
{
return
seg.st.x >= min(xl,xr) && seg.st.x <= max(xl,xr)
&& seg.ed.x >= min(xl,xr) && seg.ed.x <= max(xl,xr)
&& seg.st.y >= min(yt,yb) && seg.st.y <= max(yt,yb)
&& seg.ed.y >= min(yt,yb) && seg.ed.y <= max(yt,yb);
}
int main()
{
int n;
scanf("%d",&n);
while( n-- )
{
seg.readl();
scanf("%lf %lf %lf %lf",&xl,&yt,&xr,&yb);
set_rec();
bool ok = false;
for( int i = 0;i<4;++i)
{
if(seg_inter_seg(seg,rec[i]))
{
ok = true;
break;
}
}
if( ok == false )
if( seg_in_rec())
ok = true;
if( ok )
puts("T");
else
puts("F");
}
return 0;
}