台球碰撞

在平面直角坐标系下,台球桌是一个左下角在(0,0),右上角在(L,W)的矩形。有一个球心在(x,y),半径为R的圆形母球放在台球桌上(整个球都在台球桌内)。受撞击后,球沿极角为a的射线(即:x正半轴逆时针旋转到此射线的角度为a)飞出,每次碰到球桌时均发生完全弹性碰撞(球的速率不变,反射角等于入射角)。

如果球的速率为vs个时间单位之后球心在什么地方?

输入
 
输入文件最多包含25组测试数据,每个数据仅一行,包含8个正整数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),含义见题目描述。L=W=x=y=R=a=v=s=0表示输入结束,你的程序不应当处理这一行。

输出
对于每组数据,输出仅一行,包含两个实数x, y,表明球心坐标为(x,y)。x和y应四舍五入保留两位小数。

样例输入
100 100 80 10 5 90 2 23
110 100 70 10 5 180 1 9999
0 0 0 0 0 0 0 0
样例输出
80.00 56.00
71.00 10.00

分析:高中时候的运动分解,我想我已经还给老师了,


大致懂了,先贴代码:
//起点 A 终点 B  与长方形边界交点C 
#include <stdio.h>
#include <math.h>
 
int    n = 0;
double    X1, Y1, x, y, R;
 
void endpoint( double L, double W ); /* x,y is start point  X1,Y1 is end point */
 
 
int main()
 
{
    double L, W, a, v, s;
 
    scanf( "%lf%lf%lf%lf%lf%lf%lf%lf", &L, &W, &x, &y, &R, &a, &v, &s );
 
 
    while ( L != 0 && W != 0 && x != 0 && y != 0 && R != 0 && a != 0 && v != 0 && s != 0 )
    {
        a    = a * asin( 1 ) * 2 / 180;
        //初始结束点X Y 
        X1    = x + s*v*cos( a );
        Y1 = y + s*v*sin( a );
 
 
        while ( X1<0 || X1>L || Y1<0 || Y1>W )//判断是否出界,出界一直循环 
        {
            endpoint( L - R, W - R );
        }
        if ( X1 >= 0 + R && X1 <= L && Y1 >= 0 + R && Y1 <= W )
        {
            printf( "%.2lf %.2lf
", X1, Y1 );
        }
        scanf( "%lf%lf%lf%lf%lf%lf%lf%lf", &L, &W, &x, &y, &R, &a, &v, &s );
    }
 
 
/*for(int i=0;i<n;i++)
 * {
 * printf("%.2lf %.2lf
",xx[i],yy[i]);
 *
 * }*/
 
    return(0);
}
 
 
void endpoint( double L, double W )//边界已经减去R 减去的仅仅是上右两个方向的,其他方向没变 
{
    double upx, downx, righty, lefty, slope;
    slope = (Y1 - y) / (X1 - x);//tan# 
 
    upx    = (W - y) / slope + x;//x++ 
    downx    = (0.0 + R - y) / slope + x;//x--
 
    righty    = slope * (L - x) + y;//y++
    lefty    = slope * (0.0 + R - x) + y;//y-- 
 
    if ( Y1 > W && y < W && upx >= 0 + R && upx <= L )//   与上边相交 Y1>W  
    {
        x    = upx;//往上去 
        y    = W;
 
        Y1 = Y1 - 2 * (Y1 - W);
 
        return;
    }  /* yu shangbianjie xiang jiao */
    else
    if ( Y1 < 0 + R && y > 0 + R && downx >= 0 + R && downx <= L )//   与下边相交 
    {
        x    = downx;//往下去 
        y    = 0 + R;
 
        Y1 = Y1 - 2 * (Y1 - R);
 
        return;
    } /* yu xiabianjie */
    else
 
    if ( X1 > L && x < L && righty >= 0 + R && righty <= W )// 与右边相交 
    {
        x    = L;
        y    = righty;//y往右去 
 
        X1 = X1 - 2 * (X1 - L);
 
        return;
    } /* YU YOU BIANJIE */
    else
    if ( X1 < 0 + R && x > 0 + R && lefty >= 0 + R && lefty <= W )// 与左边相交 
    {
        x    = 0 + R;
        y    = lefty;// y往左去 
 
        X1 = X1 - 2 * (X1 - R);
 
 
        return;
    }
 
    return;
}
View Code
原文地址:https://www.cnblogs.com/helloworld2019/p/10438355.html