zcmu-1756 billiard ball collision (orthogonal decomposition)

Posted by kerepuki09 on Mon, 16 Dec 2019 20:22:50 +0100

Problem D: Billiards collision

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 91  Solved: 37
[Submit][Status][Web Board]

Description

In the plane rectangular coordinate system, the billiard table is a rectangle with the lower left corner at (0,0) and the upper right corner at (L,W). There is a round ball with a center (x,y) and a radius of R on the billiard table (the whole ball is in the billiard table). After being hit, the ball flies out along the ray with polar angle a (i.e. the angle of rotation of the positive half axis of X to this ray is a) and every time it touches the ball table, it will have a full elastic collision (the speed of the ball is constant, and the reflection angle is equal to the incident angle). If the velocity of the ball is v, where is the center of the ball after s time units?

Input

The input file contains at most 25 groups of test data, each data is only one line, including 8 positive integers L,W,x,y,R,a,v,s (100 < = L, w < = 105, 1 < = R < = 5, R < = x < = L-R, R < = y < = W-R, 0 < = a < 360, 1 < = V, s < = 105). See the title description for the meaning. L=W=x=y=R=a=v=s=0 indicates the end of the input. Your program should not process this line.

Output

For each group of data, the output is only one line, including two real numbers x, y, indicating that the spherical center coordinate is (x,y). X and Y shall be rounded to two decimal places

Sample Input

100 100 80 10 5 90 2 23 1

10 100 70 10 5 180 1 9999

0 0 0 0 0 0 0 0

Sample Output

80.00 56.00

71.00 10.00

//If the collision of the ball is regarded as the collision of the points, then from the tangent, the range of the rectangle size to x is [r,L-r], and the range of y is [r,W-r]. Then the orthogonal decomposition of the velocity is considered,;

//%. 2f will automatically round

//100 100 80 10 5 270 2 23
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;
const double PI=acos(-1.0);
int main()
{
    double l,w,x,y,r,a,v,s;
    while(scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&l,&w,&x,&y,&r,&a,&v,&s))
    {
        if(!l&&!w&&!x&&!y&&!r&&!a&&!v&&!s)
            break;
        int flagx,flagy;//Speed direction
        l=l-r;
        w=w-r;
        double vx,vy;
        if(a>=0&&a<=90)flagx=1,flagy=1;
        else if(a>=90&&a<=180)flagx=-1,flagy=1,a=180-a;
        else if(a>=180&&a<=270)flagx=-1,flagy=-1,a=a-180;
        else flagx=1,flagy=-1,a=360-a;
        if(a==90)vx=0,vy=v;
        else if(a==0)vx=v,vy=0;
        else
        {
            vx=v*cos(a/180*PI);
            vy=v*sin(a/180*PI);
        }
        double x1,y1;
        double time=0;
        double disx,disy;
        while(1)
        {
            if(flagx==1)disx=l-x;
            else disx=x-r;
            if(flagy==1)disy=w-y;
            else disy=y-r;
            if(disx/vx>disy/vy||vx==0)
            {
                double t=disy/vy;
                //cout<<disy<<"***"<<vy<<endl;
                if(time+t<s)
                {
                    x1=x+flagx*vx*t;
                    y1=y+flagy*vy*t;
                    time+=t;
                    x=x1;y=y1;flagy=-flagy;
                }else if(time+t==s)
                {
                    x1=x+flagx*vx*t;
                    y1=y+flagy*vy*t;
                    break;
                }else
                {
                    t=s-time;
                    x1=x+flagx*vx*t;
                    y1=y+flagy*vy*t;
                    break;
                }
            }else if(disx/vx<=disy/vy||vy==0)
            {
                double t=disx/vx;
                if(time+t<s)
                {
                    x1=x+flagx*vx*t;
                    y1=y+flagy*vy*t;
                    time+=t;
                    x=x1;y=y1;flagx=-flagx;
                }else if(time+t==s)
                {
                    x1=x+flagx*vx*t;
                    y1=y+flagy*vy*t;
                    break;
                }else
                {
                    t=s-time;
                    x1=x+flagx*vx*t;
                    y1=y+flagy*vy*t;
                    break;
                }
            }
            //cout<<x1<<" "<<y1<<time<<endl;
        }
        printf("%.2f %.2f\n",x1,y1);
    }
    return 0;
}