ZOJ 3728 Collision 計算幾何

/*
ZOJ3728 Collision 計算幾何

這個計算幾何不難,但是有兩處沒有考慮到
1.沒有注意速度的方向
2.當時間爲零的時候輸出“0”,而不是“0.000”
*/
#include<stdio.h>
#include<math.h>
double eps=1e-10;
int dbcmp(double a)
{
	if(a>eps) return 1;
	else if(a<(-eps)) return -1;
	return 0;
}
struct point
{
	point()
	{
		x=y=0;
	}
	point(double a,double b)
	{
		x=a;
		y=b;
	}
    double x,y;
};

double xmult(point p1,point p2,point p0)
{
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}

//兩點距離
double distance(point p1,point p2)
{
    return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}

point intersection(point u1,point u2,point v1,point v2)
{
    point ret=u1;
    double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))
		/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
    ret.x+=(u2.x-u1.x)*t;
    ret.y+=(u2.y-u1.y)*t;
    return ret;
}

double disptoline(point p,point l1,point l2)
{
    return fabs(xmult(p,l1,l2))/distance(l1,l2);
}

void intersection_line_circle(point c,double r,point l1,point l2,point& p1,point& p2)
{
    point p=c;
    double t;
    p.x+=l1.y-l2.y;
    p.y+=l2.x-l1.x;
    p=intersection(p,c,l1,l2);
    t=sqrt(r*r-distance(p,c)*distance(p,c))/distance(l1,l2);
    p1.x=p.x+(l2.x-l1.x)*t;
    p1.y=p.y+(l2.y-l1.y)*t;
    p2.x=p.x-(l2.x-l1.x)*t;
    p2.y=p.y-(l2.y-l1.y)*t;
}

int main()
{
	double rm,R,r,x,y,vx,vy;
	while(scanf("%lf%lf%lf%lf%lf%lf%lf",&rm,&R,&r,&x,&y,&vx,&vy)!=EOF)
	{
		double dist = disptoline(point(0,0),point(x,y),point(x+vx,y+vy));
		if(dbcmp(dist-R-r)>=0)
		{
			//printf("%.3lf\n",0);
			printf("0\n");
			continue;
		}
		
		point o1,o2;
		intersection_line_circle(point(0,0),R+r,point(x,y),point(x+vx,y+vy),o1,o2);

		o2.x=o1.x-x;
		o2.y=o1.y-y;

		double aa=o2.x*vx+o2.y*vy;
		if(dbcmp(aa)<0)
		{
			printf("0\n");
			//printf("%.3lf\n",0);
			continue;
		}

		if(dbcmp(dist-r-rm)>=0)
		{
			point j1,j2;
			intersection_line_circle(point(0,0),R+r,point(x,y),point(x+vx,y+vy),j1,j2);
			double dx=j2.x-j1.x;
			double dy=j2.y-j1.y;
			double time;
			if(dbcmp(vy)!=0)
			{
				time=dy/vy;
			}else
			{
				time=dx/vx;
			}
			if(dbcmp(time)<0)
			{
				time=-time;
			}
			printf("%.3lf\n",time);
			continue;
		}else
		{
			
			point j1,j2,j3,j4;
			intersection_line_circle(point(0,0),R+r,point(x,y),point(x+vx,y+vy),j1,j2);
			intersection_line_circle(point(0,0),rm+r,point(x,y),point(x+vx,y+vy),j3,j4);
			
			point a=j1,b;
			if(distance(a,j3)>distance(a,j4))
			{
				b=j4;
			}else
			{
				b=j3;
			}
			double dx=a.x-b.x,dy=a.y-b.y;
			double time;
			if(dbcmp(vy)!=0)
			{
				time=dy/vy;
			}else
			{
				time=dx/vx;
			}
			if(dbcmp(time)<0)
			{
				time=-time;
			}
			printf("%.3lf\n",time*2);
		}
	}
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章