POJ - 1410 Intersection

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lidengdengter/article/details/82054450

题目链接

判断线段是否和矩形相交或者在矩形内或者在矩形边上,是则输出T,否则输出F。

一开始自己没看清题意,直接判断矩形四条边是否和线段相交,一直wa。看了题解才知道,还有在矩形内和矩形边上,这三种情况都单独讨论。

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const double eps=1e-8;

int sgn(double x){
	if(fabs(x)<eps)
		return 0;
	if(x<0)
		return -1;
	else return 1;
}

struct point{
	double x,y;
	point(){}
	point(double sx,double sy):x(sx),y(sy){}
	point operator -(const point &w)const{  //相减 
		return point(x-w.x,y-w.y);
	}
	double operator ^(const point &w)const{ //叉积 
		return x*w.y-y*w.x;
	}
	double operator *(const point &w)const{ //点积 
		return x*w.x+y*w.y;
	}
}p[100];

struct line{
	point st,ed;
	line(){}
	line(point sa,point sb):st(sa),ed(sb){}
}seg; 

bool isCross(line a,line 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)&&
	sgn((b.st-a.ed)^(a.st-a.ed))*sgn((b.ed-a.ed)^(a.st-a.ed))<=0&&
	sgn((a.st-b.ed)^(b.st-b.ed))*sgn((a.ed-b.ed)^(b.st-b.ed))<=0;
} 

bool isOn(point a,line c){  //是否在线上 
	return 
	sgn((c.st-a)^(c.ed-a))==0 &&
	sgn((a.x-c.st.x)*(a.x-c.ed.x))<=0&&
	sgn((a.y-c.st.y)*(a.y-c.ed.y))<=0;
}

int isIn(point a,point p[],int n){ //是否在多边形内 
	for(int i=0;i<n;i++){
		double res=((p[i]-a)^(p[(i+1)%n]-a));
		if(sgn(res)<0) 
			return -1; //在多边形外
		else if(isOn(a,line(p[i],p[(i+1)%n])))
			return 0;  //在线上 
	} 
	return 1;
}

int main(){
	int T;
	scanf("%d",&T);
	double x1,x2,y1,y2;
	while(T--){
		scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);  
		seg=line(point(x1,y1),point(x2,y2));
		
		scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
		if(x1>x2) swap(x1,x2);
		if(y1>y2) swap(y1,y2);
		 
		p[0]=point(x1,y1);
		p[1]=point(x2,y1);
		p[2]=point(x2,y2);
		p[3]=point(x1,y2);
		
		if(isCross(seg,line(p[0],p[1]))){  
			printf("T\n");
			continue;		
		}
		if(isCross(seg,line(p[1],p[2]))){  
			printf("T\n");
			continue;		
		}
		if(isCross(seg,line(p[2],p[3]))){  
			printf("T\n");
			continue;		
		}
		if(isCross(seg,line(p[3],p[0]))){  
			printf("T\n");
			continue;		
		}
		if(isIn(seg.st,p,4)>=0||isIn(seg.ed,p,4)>=0){
			printf("T\n");
			continue;
		}
		printf("F\n");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/lidengdengter/article/details/82054450