ZOJ 1472 Overlapping Shapes

应该算巨水了吧。。

不过写这道题是为了写点到线段的距离。

圆圆、矩矩不多说了,圆矩就看圆心到矩形四条边的距离是否不大于半径,某一不大于yes,都大于no。

思想如下,点与线段的位置关系分为3类:C1,C2,C3

ZOJ 1472 Overlapping Shapes_第1张图片

图中AB为线段,C为点出现的情况。灰线代表过A、B与AB垂直的直线,黑线表示向量

从图中可以很容易看出来C2和C3算一种情况,在两条垂线的一侧。

注意C2,向量AC2,AB,可以看出向量夹角为钝角,同时向量BC2与向量BA夹角为锐角,

同理向量BC3,BA夹角为钝角,AC3,AB夹角为锐角。

那么什么公式可以表示向量夹角为钝角还是锐角呢?点积。

设t=向量AB,AC的点积*向量BA,BC的点积

若t<0则在两侧,点到线段AB的距离=min(|AC|,|BC|)

否则点到线段AB的距离=ABC的面积/|AB|

代码:

#include<stdio.h>
#include<string.h>
#include<math.h>
#define eps 1e-8
struct point{
	double x,y;
};
struct tr{
	point a,b,c,d;
}u,v;
struct circle{
	point o;
	double r;
}cu,cv;
double chaji(point a,point b,point c){
	return (c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x);
}
int dianji(point a,point b,point c){
	double t;
	t=(c.x-a.x)*(b.x-a.x)+(c.y-a.y)*(b.y-a.y);
	if(t<-eps)return -1;
	if(t>eps)return 1;
	return 0;
}
double dis(point a,point b){
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double disl(point a,point b,point c){
	if(dianji(b,c,a)*dianji(c,b,a)<0)
		return fmin(dis(a,b),dis(a,c));
	else
	    return fabs(chaji(a,b,c))/dis(b,c);
}
bool tin(tr u,point v){
	if(v.x>u.a.x-eps&&v.x<u.c.x+eps&&v.y>u.c.y-eps&&v.y<u.a.y+eps)
	    return 1;
	return 0;
}
void solve(circle u,tr v){
	if(disl(u.o,v.a,v.b)<u.r+eps||
	   disl(u.o,v.b,v.c)<u.r+eps||
	   disl(u.o,v.c,v.d)<u.r+eps||
	   disl(u.o,v.d,v.a)<u.r+eps)
		puts("yes");
	else
	    puts("no");
}
int main(){
	char name1[50],name2[50];
	int cs,f1,f2;
	double dr;
	scanf("%d",&cs);
	while(cs--){
		scanf("%s",name1);
		if(!strcmp(name1,"circle"))
		    scanf("%lf%lf%lf",&cu.r,&cu.o.x,&cu.o.y),f1=0;
		else{
		    scanf("%lf%lf%lf%lf",&u.a.x,&u.a.y,&u.c.x,&u.c.y);
			u.b.x=u.a.x;u.b.y=u.c.y;
			u.d.x=u.c.x;u.d.y=u.a.y;
			f1=1;
		}
        scanf("%s",name2);
		if(!strcmp(name2,"circle"))
		    scanf("%lf%lf%lf",&cv.r,&cv.o.x,&cv.o.y),f2=0;
		else{
		    scanf("%lf%lf%lf%lf",&v.a.x,&v.a.y,&v.c.x,&v.c.y);
			v.b.x=v.a.x;
			v.b.y=v.c.y;
			v.d.x=v.c.x;
			v.d.y=v.a.y;
			f2=1;
		}
	if(!f1&&!f2){
		dr=dis(cu.o,cv.o);
		if((dr-eps<cu.r+cv.r)&&(dr+eps>fabs(cu.r-cv.r)))
			puts("yes");
		else
		    puts("no");
	}
	if(f1&&f2){
		if(tin(u,v.a)||tin(u,v.b)||tin(u,v.c)||tin(u,v.d)||
		   tin(v,u.a)||tin(v,u.b)||tin(v,u.c)||tin(v,u.d))
			puts("yes");
		else
		    puts("no");
	}
	if(!f1&&f2)solve(cu,v);
	if(f1&&!f2)solve(cv,u);
	}
	return 0;
}

 

你可能感兴趣的:(ZOJ 1472 Overlapping Shapes)