ZOJ 3728——Collision

来源:互联网 发布:网络司法拍卖司法解释 编辑:程序博客网 时间:2024/05/17 18:47

There's a round medal fixed on an ideal smooth table, Fancy is trying to throw some coins and make them slip towards the medal to collide. There's also a round range which shares exact the same center as the round medal, and radius of the medal is strictly less than radius of the round range. Since that the round medal is fixed and the coin is a piece of solid metal, we can assume that energy of the coin will not lose, the coin will collide and then moving as reflect.

Now assume that the center of the round medal and the round range is origin ( Namely (0, 0) ) and the coin's initial position is strictly outside the round range. Given radius of the medalRm, radius of coin r, radius of the round range R, initial position (x, y) and initial speed vector (vx,vy) of the coin, please calculate the total time that any part of the coin is inside the round range.

Please note that the coin might not even touch the medal or slip through the round range.

Input

There will be several test cases. Each test case contains 7 integers Rm,R, r, x, y, vx and vy in one line. Here 1 ≤Rm < R ≤ 2000, 1 ≤ r ≤ 1000, R +r < |(x, y)| ≤ 20000, 1 ≤ |(vx, vy)| ≤ 100.

Output

For each test case, please calculate the total time that any part of the coin is inside the round range. Please output the time in one line, an absolute error not more than 1e-3 is acceptable.

Sample Input

5 20 1 0 100 0 -15 20 1 30 15 -1 0

Sample Output

30.00029.394

题目大意是一个奖牌放在原点,奖牌外面有一个圈,一个硬币在光滑平面上移动,如果撞到奖牌就会反弹。求硬币在圈内的总时间。

思路:将硬币运动看作一条射线。如果硬币运动过程中只是跟圈相离或相切那么答案就是0。如果硬币能到达圈里面,那么判断硬币跟奖牌是否相交(相切跟相离是一样的)。如果相离或者相切,那么奖牌相当于没有。如果相交了,那么求出碰撞之前运动的时间乘以2就是答案。

求解过程中注意判断硬币与圈是否相交不是用圈的半径,因为只要硬币有一部分进去就要记时间,所以应当判断硬币的运动直线与以原点为圆心,Rm+r为半径的圆的交点。与奖牌的交点也一样。

代码如下:

#include<iostream>#include<cmath>#include<vector>#include<iomanip>using namespace std;struct Point{double x,y;Point(double x=0,double y=0):x(x),y(y){}};typedef Point Vector;Vector operator + (Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);}Vector operator - (Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);}Vector operator * (Vector a,double p){return Vector(a.x*p,a.y*p);}Vector operator / (Vector a,double p){return Vector(a.x/p,a.y/p);}bool operator < (const Point& a,const Point &b){return a.x<b.x||(a.x==b.x&&a.y<b.y);}const double eps=1e-10;int dcmp(double x){if(fabs(x)<eps)return 0;else return x<0?-1:1;}bool operator ==(const Point& a,const Point& b){return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;}double Dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;}double Length(Vector a){return sqrt(Dot(a,a));}double Angle(Vector a,Vector b){return acos(Dot(a,b)/Length(a)/Length(b));}double Cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;}Point GetLineIntersection(Point p,Vector v,Point q,Vector w){Vector u=p-q;double t=Cross(w,u)/Cross(v,w);return p+v*t;}Vector Rotate(Vector A,double rad){return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));}struct Circle{Point c;double r;Circle(Point c,double r):c(c),r(r){}};struct Line{Point p;Vector v;Line(Point p,Vector v):p(p),v(v){}};int getLineCircleIntersection(Line L,Circle C,double &t1,double &t2,vector<Point>& sol){double a=L.v.x,b=L.p.x-C.c.x,c=L.v.y,d=L.p.y-C.c.y;double e=a*a+c*c;double f=2*(a*b+c*d);double g=b*b+d*d-C.r*C.r;double delta=f*f-4*e*g;//cout<<delta<<endl;if(dcmp(delta)<0)return 0;if(dcmp(delta)==0)return 1;delta=sqrt(delta);t1=(-f-delta)/(2*e);sol.push_back(Point(L.p.x+t1*L.v.x,L.p.y+t1*L.v.y));t2=(-f+delta)/(2*e);sol.push_back(Point(L.p.x+t2*L.v.x,L.p.y+t2*L.v.y));return 2;}int main(){//freopen("data.txt","r",stdin);ios::sync_with_stdio(false);double Rm,R,r,x,y,vx,vy;while(cin>>Rm>>R>>r>>x>>y>>vx>>vy){double rr=R+r;Line L(Point(x,y),Vector(vx,vy));double t1,t2;vector<Point> sol;int t=getLineCircleIntersection(L,Circle(Point(0,0),rr),t1,t2,sol);//cout<<"zzz"<<endl;if(t!=2){cout<<0<<endl;continue;}if(t1<0){cout<<0<<endl;continue;}double tt1,tt2;vector<Point> sol1;int nt=getLineCircleIntersection(L,Circle(Point(0,0),Rm+r),tt1,tt2,sol1);//cout<<"nt="<<nt<<endl;if(nt<2){//cout<<"x"<<endl;double time=Length(sol[1]-sol[0])/Length(Vector(vx,vy)); cout<<setiosflags(ios::fixed)<<setprecision(3)<<fabs(time)<<endl;}else {tt1=tt1<tt2?tt1:tt2;Point crush=Point(x,y)+Point(vx,vy)*tt1;Vector z=crush-Point(0,0);double tt=t1<t2?t1:t2;Point s=Point(L.p.x+tt*L.v.x,L.p.y+tt*L.v.y);double time=(Length(s-crush))/Length(Vector(vx,vy));cout<<setiosflags(ios::fixed)<<setprecision(3)<<fabs(time*2)<<endl;}//cout<<"~~~~~~"<<endl;}return 0;}




0 0
原创粉丝点击