思路:分三种情况讨论。1,碰撞;2,在其中;3,不飞进去。(向量求夹角)
注意碰撞的时候路径不是简单的半径乘以2。
#include<stdio.h>
#include<math.h>
int main()
{
double Rm,R,r,x,y,vx,vy;
double aa,a,a1,a2; // 用cos来表示角度;
double d,t,tt,v,l;
double r1,r2; //r1表示与大圆相切的距离,r2表示与小圆相切的距离;
while(~scanf("%lf%lf%lf%lf%lf%lf%lf",&Rm,&R,&r,&x,&y,&vx,&vy))
{
t=x*x+y*y; //提前把计算步骤给表示出来,减低精度损失;
v=sqrt(vx*vx+vy*vy); //硬币的合速度;
d=sqrt(t); //硬币与坐标原点的距离;
r1=R+r; //硬币与大圆相切的时候两心之间的距离;
r2=Rm+r; //硬币与小圆相切的时候两心之间的距离;
a=-(x*vx+y*vy)/(d*v); //两向量(两心连线向量,合速度)之间的余弦值;
aa=acos(a); //两向量夹角值;
a1=sqrt(1.0-r1*r1/t); //与大圆相切的时候夹角;
a2=sqrt(1.0-r2*r2/t); //与小圆相切的时候夹角;
if(aa>=acos(a1)) //当不飞进大圆区域时;
printf("0.000\n");
else if(aa<acos(a2)) //当与小圆碰撞的时候,会反弹;
{
d=d*d*(1-a*a);
l=sqrt(r1*r1-d)-sqrt(r2*r2-d);
tt=2.0*l/v;
printf("%.3lf\n",tt);
}
else //当只在大圆区域飞的时候;
{
l=2*sqrt(r1*r1-d*d*(1-a*a));
tt=l/v;
printf("%.3lf\n",tt);
}
}
return 0;
}