小球在矩形框内45°碰撞问题

来源:互联网 发布:兼职淘宝客服好不好做 编辑:程序博客网 时间:2024/05/29 13:05

问题描述:

在一个矩形框内长w, 高h,现在在底边某一点举例左端点x位置处有一弹性小球(可视为质点)向右上方45°发射,碰撞忽略能量损耗,继续45°弹出,输出在前n次碰撞到底边时每次碰撞的位置。

这里写图片描述

首先说一种比较繁琐的思路:

碰撞本身是一个过程,我们只需要将所有的可能性考虑到位就好,首先,我们定义如下几个变量用来确定当前的状态:

  1. pos 表示当前的位置在哪条边上,我们默认从顶上顺时针分别为1, 2, 3, 4

  2. s1, s2, h1, h2:分别用来表示在横和竖的四条边上的位置,默认以左端点或下端点为0, 左边的竖线代表s1,右边的竖线代表s2,上边的横线为h1, 下边的为h2

  3. direction:用来表示当前的方向,逆时针碰撞还是顺时针碰撞

然后我们就能根据题意确定初始状态:

direction = -1;
pos = 3;
h2 = x;

解决代码如下:

    static void ball(int w, int h, int x, int n){        int s1, s2, h1, h2;        s1 = s2 = h1 = h2 = 0;        int direction = -1;        int pos = 3;        int count = 0;        h2 = x;        //要求输出前n次碰撞到底边的位置        while(count != n + 1){            //逆时针            if(direction == -1){                //判断当前位置                if(pos == 1){                    //判断是否超越临边的长度                    if(h1 > h){                        //确定下次的位置(包括在哪条边上,距离端点的位置长度以及下次碰撞的方向)                        pos = 3;                        h2 = h1 - h;                        direction = 1;                        continue;                    }else{                        pos = 4;                        direction = -1;                        s1 = h - h1;                        continue;                    }                }else if(pos == 2){                    if(h - s2 > w){                        pos = 4;                        direction = 1;                        s1 = s2 + w;                        continue;                    }else{                        pos = 1;                        h1 = w - (h - s2);                        direction = -1;                        continue;                    }                }else if(pos == 3){                    count ++;                    if(count != 1){                        System.out.printf("%d ", h2);                    }                    if(w - h2 > h){                        h1 = h2 + h;                        pos = 1;                        direction = 1;                        continue;                    }else{                        s2 = w - h2;                        pos = 2;                        direction = -1;                        continue;                    }                }else{                    if(s1 > w){                        pos = 2;                        s2 = s1 - w;                        direction = 1;                        continue;                    }else{                        pos = 3;                        h2 = s1;                        direction = -1;                        continue;                    }                }            }else{                //顺时针                if(pos == 1){                    if(w - h1 > h){                        pos = 3;                        h2 = h1 + h;                        direction = -1;                        continue;                    }else{                        pos = 2;                        s2 = h - (w - h1);                        direction = 1;                        continue;                    }                }else if(pos == 2){                    if(s2 > w){                        s1 = s2 - w;                        pos = 4;                        direction = -1;                        continue;                    }else{                        pos = 3;                        h2 = w - s2;                        direction = 1;                        continue;                    }                }else if(pos == 3){                    //当在底边时要考虑输出                    count ++;                    //初始位置不计数                    if(count != 1){                        System.out.printf("%d ", h2);                    }                    if(h2 > h){                        pos = 1;                        direction = -1;                        h1 = h2 - h;                        continue;                    }else{                        pos = 4;                        direction = 1;                        s1 = h2;                        continue;                    }                }else{                    if((h -h1) >  w){                        pos = 2;                        direction = -1;                        s2 = h - h1 - w;                        continue;                    }else{                        pos = 1;                        direction = 1;                        h1 = h - s1;                        continue;                    }                }            }        }    }

还有一种比较有技巧的做法,通过题意我们了解到碰撞是45°的,所以三角形—>等腰,我们能想到每次碰撞回到底边时,竖直方向的位移距离等于水平方向的位移距离(无论是否是碰撞到临边还是对边,无论是顺时针碰撞还是逆时针碰撞),所以我们可以根据这个结论得出:当竖直方向运动2×h距离时就会回到底边,并且底边的位移距离也等于2×h,所以到现在我们就将问题转换到了在底边运动2×h后的位置,我们要考虑到到达两端点后的反向问题。

也就是说我们要在底边滑动2×h后输出当前位置,解决代码如下:

    static void ball2(int w, int h, int x, int n){        //记录当前位置        int pos = x;        //记录当前移动的方向        char flag = 'r';        //每次需要移动2 × h的距离        int temp = 2 * h;        //nwhile(n-- != 0){            temp = 2 * h;            while(temp != 0){                if(flag == 'l'){                    if(temp > pos){                        temp -= pos;                        pos = 0;                        flag = 'r';                        continue;                    }else{                        pos -= temp;                        System.out.printf("%d ", pos);                        break;                    }                }else{                    if(temp > w - pos){                        temp -= (w - pos);                        pos = w;                        flag = 'l';                        continue;                    }else{                        pos += temp;                        System.out.printf("%d ", pos);                        break;                    }                }            }        }    }

========================
两种方法及测试代码汇总如下:

import java.util.Scanner;/** * Created by zhuxinquan on 17-3-9. * 一个矩形内从底边一点开始斜向上45°发出一个小球(直径忽略),然后反弹 * 求在n次碰撞到底边时每次的位置 */public class Crash{    static void ball2(int w, int h, int x, int n){        int pos = x;        char flag = 'r';        int temp = 2 * h;        while(n-- != 0){            temp = 2 * h;            while(temp != 0){                if(flag == 'l'){                    if(temp > pos){                        temp -= pos;                        pos = 0;                        flag = 'r';                        continue;                    }else{                        pos -= temp;                        System.out.printf("%d ", pos);                        break;                    }                }else{                    if(temp > w - pos){                        temp -= (w - pos);                        pos = w;                        flag = 'l';                        continue;                    }else{                        pos += temp;                        System.out.printf("%d ", pos);                        break;                    }                }            }        }    }    static void ball(int w, int h, int x, int n){        int s1, s2, h1, h2;        s1 = s2 = h1 = h2 = 0;        int direction = -1;        int pos = 3;        int count = 0;        h2 = x;        while(count != n + 1){            //逆时针            if(direction == -1){                if(pos == 1){                    if(h1 > h){                        pos = 3;                        h2 = h1 - h;                        direction = 1;                        continue;                    }else{                        pos = 4;                        direction = -1;                        s1 = h - h1;                        continue;                    }                }else if(pos == 2){                    if(h - s2 > w){                        pos = 4;                        direction = 1;                        s1 = s2 + w;                        continue;                    }else{                        pos = 1;                        h1 = w - (h - s2);                        direction = -1;                        continue;                    }                }else if(pos == 3){                    count ++;                    if(count != 1){                        System.out.printf("%d ", h2);                    }                    if(w - h2 > h){                        h1 = h2 + h;                        pos = 1;                        direction = 1;                        continue;                    }else{                        s2 = w - h2;                        pos = 2;                        direction = -1;                        continue;                    }                }else{                    if(s1 > w){                        pos = 2;                        s2 = s1 - w;                        direction = 1;                        continue;                    }else{                        pos = 3;                        h2 = s1;                        direction = -1;                        continue;                    }                }            }else{                //顺时针                if(pos == 1){                    if(w - h1 > h){                        pos = 3;                        h2 = h1 + h;                        direction = -1;                        continue;                    }else{                        pos = 2;                        s2 = h - (w - h1);                        direction = 1;                        continue;                    }                }else if(pos == 2){                    if(s2 > w){                        s1 = s2 - w;                        pos = 4;                        direction = -1;                        continue;                    }else{                        pos = 3;                        h2 = w - s2;                        direction = 1;                        continue;                    }                }else if(pos == 3){                    count ++;                    if(count != 1){                        System.out.printf("%d ", h2);                    }                    if(h2 > h){                        pos = 1;                        direction = -1;                        h1 = h2 - h;                        continue;                    }else{                        pos = 4;                        direction = 1;                        s1 = h2;                        continue;                    }                }else{                    if((h -h1) >  w){                        pos = 2;                        direction = -1;                        s2 = h - h1 - w;                        continue;                    }else{                        pos = 1;                        direction = 1;                        h1 = h - s1;                        continue;                    }                }            }        }    }    public static void main(String[] args){        int w, h, x, n;        Scanner in = new Scanner(System.in);        w = in.nextInt();        h = in.nextInt();        x = in.nextInt();        n = in.nextInt();        ball2(w, h, x, n);    }}
0 0
原创粉丝点击