51nod3140 矩形的秘密

3140 矩形的秘密

在平面上,有一个矩形和一条线段,其中矩形的四边均平行于坐标轴。请你判断这个矩形和给出的线段是否相交,相交输出T,否则输出F

输入

第一行一个整数n表示数据组数。
接下来n行,每行8个整数xstart ystart xend yend x1 y1 x2 y2,其中(xstart,ysta
rt)和(xend,yend)是线段的端点坐标,(x1,y1)和(x2,y2)是矩形一对对角顶点的坐标。

输出

对于每组数据,如果矩形和线段有交点则输出T,否则输出F

数据范围

对于100%的数据: n<=50

输入样例

输入样例1:
1
4 9 11 2 1 5 7 1

输出样例

输出样例1:
F

解析:

判断一下线段是否和矩形的四条边相交,如果没有的话再判断下是否在矩形内部。

放代码:

#include <iostream>
#include<cstdio>
#include<cmath>
using namespace std;
typedef double db;
const db eps=1e-6;
struct Point{
	db x,y;
	Point(db x=0,db y=0):x(x),y(y){}
};
typedef Point Vector;
int sgn(db x){
	if(fabs(x)<eps) return 0;
	if(x>0) return 1;
	return -1;
}
Vector operator+(Vector a,Vector b){
	return Vector(a.x+b.x,a.y+b.y);
}
Vector operator-(Vector a,Vector b){
	return Vector(a.x-b.x,a.y-b.y);
}
Vector operator*(Vector a,db p){
	return Vector(a.x*p,a.y*p);
}
Vector operator/(Vector a,db p){
	return Vector(a.x/p,a.y/p);
}
db Cross(Vector a,Vector b){
	return a.x*b.y-a.y*b.x;
}
db Dot(Vector a,Vector b){
	return a.x*b.x+a.y*b.y;
}
bool OnSegment(Point p, Point a1, Point a2){
    return sgn(Cross(a1-p, a2-p)) == 0 && sgn(Dot(a1-p, a2-p)) < 0;
}
bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2){
    double c1 = Cross(a2-a1, b1-a1), c2 = Cross(a2-a1, b2-a1);
    double c3 = Cross(b2-b1, a1-b1), c4 = Cross(b2-b1, a2-b1);
    if(!sgn(c1) || !sgn(c2) || !sgn(c3) || !sgn(c4)){
        bool f1 = OnSegment(b1, a1, a2);
        bool f2 = OnSegment(b2, a1, a2);
        bool f3 = OnSegment(a1, b1, b2);
        bool f4 = OnSegment(a2, b1, b2);
        bool f = (f1|f2|f3|f4);
        return f;
    }
    return (sgn(c1)*sgn(c2) < 0 && sgn(c3)*sgn(c4) < 0);
}
struct Line{
	Point p,v;
};
int main(int argc, char** argv) {
	int n;
	cin>>n;
	while(n--){
		db lx,ly,rx,ry,sx,sy,ex,ey;
		cin>>sx>>sy>>ex>>ey>>lx>>ly>>rx>>ry;
		Line l;
		l.p.x=sx,l.p.y=sy;
		l.v.x=ex,l.v.y=ey;
		
		Line up,down,left,right;
		
		up.p.x=lx,up.p.y=ly;
		up.v.x=rx,up.v.y=ly;
		
		down.p.x=lx,down.p.y=ry;
		down.v.x=rx,down.v.y=ry;
		
		left.p.x=lx,left.p.y=ry;
		left.v.x=lx,left.v.y=ly;
		
		right.p.x=rx,right.p.y=ry;
		right.v.x=rx,right.v.y=ly;
		
		if((sx>=lx&&sx<=rx)||(sx>=rx&&sx<=lx)){
			if((sy>=ry&&sy<=ly)||(sy>=ly&&sy<=ry)){
				printf("T\n");
				continue;
			}
			
		}
		if((ex>=lx&&ex<=rx)||(ex>=rx&&ex<=lx)){
			if((ey>=ry&&ey<=ly)||(ey>=ly&&ey<=ry)){
				printf("T\n");
				continue;
			}
		}
		if(SegmentProperIntersection(l.p,l.v,up.p,up.v)||SegmentProperIntersection(l.p,l.v,down.p,down.v)||SegmentProperIntersection(l.p,l.v,left.p,left.v)||SegmentProperIntersection(l.p,l.v,right.p,right.v))
		    printf("T\n");
		else printf("F\n");
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值