poj 1410 判断线段和矩形是否相交

题意:给定一条线段的两个端点,再给定矩形顶点的两个横坐标和两个总坐标(矩形的边与坐标轴平行)。求线段和矩形是否有公共点(矩形是实心的)

思路:首先题意确实比较容易出现歧义。需要注意两点:1、矩形是实心的(The rectangle consists of four straight lines and the area in between),所以如果线段完全在矩形内部也算相交;2、给定的矩形坐标并不是按照矩形的端点坐标给出的,而需要自行判断。

那么所需判断的就是给定线段和矩形四条边是否相交,如果不相交,再判断线段是否在矩形内部。

#include <stdio.h>
#include <string.h>
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define eps 1e-10
typedef struct point{
	int x,y;
}P;
P p[4],s,t;
int n,T;
double multi(P a,P b,P c){
	return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
int inter(P x,P y,P s,P t){//判断线段xy和线段st是否相交
	double a,b,c,d;
	if(min(x.x,y.x)>max(s.x,t.x) || min(x.y,y.y)>max(s.y,t.y) ||
	min(s.x,t.x)>max(x.x,y.x) || min(s.y,t.y)>max(x.y,y.y))
		return 0;
	a = multi(x,y,s);
	b = multi(x,y,t);
	c = multi(s,t,x);
	d = multi(s,t,y);
	return a*b<eps && c*d<eps;
}
int in(P a){//判断点a是否在矩形内部
	return a.x>=p[0].x&&a.x<=p[2].x&&a.y>=p[0].y&&a.y<=p[2].y;
}
int main(){
	freopen("a.txt","r",stdin);
	scanf("%d",&T);
	while(T--){
		int i,j,flag=0;
		scanf("%d %d %d %d",&s.x,&s.y,&t.x,&t.y);	
		scanf("%d %d %d %d",&p[0].x,&p[0].y,&p[2].x,&p[2].y);
		if(p[0].x > p[2].x){
			int temp = p[0].x;
			p[0].x = p[2].x;
			p[2].x = temp;
		}
		if(p[0].y > p[2].y){
			int temp = p[0].y;
			p[0].y = p[2].y;
			p[2].y = temp;
		}//使得p[0]存放矩形的左下点,p[2]存放右上点
		p[1].x = p[2].x;
		p[1].y = p[0].y;
		p[3].x = p[0].x;
		p[3].y = p[2].y;
		for(i = 0;i<4;i++)
			if(inter(p[i],p[(i+1)%4],s,t)){//分别判断线段和矩形边是否相交
				flag = 1;
				break;
			}
		if(!flag && (in(s) || in(t)))//判断线段端点是否在矩形内部
			flag = 1;
		if(flag)
			printf("T\n");
		else
			printf("F\n");
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值