小球在矩形框内45°碰撞问题
来源:互联网 发布:兼职淘宝客服好不好做 编辑:程序博客网 时间:2024/05/29 13:05
问题描述:
在一个矩形框内长w, 高h,现在在底边某一点举例左端点x位置处有一弹性小球(可视为质点)向右上方45°发射,碰撞忽略能量损耗,继续45°弹出,输出在前n次碰撞到底边时每次碰撞的位置。
首先说一种比较繁琐的思路:
碰撞本身是一个过程,我们只需要将所有的可能性考虑到位就好,首先,我们定义如下几个变量用来确定当前的状态:
pos 表示当前的位置在哪条边上,我们默认从顶上顺时针分别为1, 2, 3, 4
s1, s2, h1, h2:分别用来表示在横和竖的四条边上的位置,默认以左端点或下端点为0, 左边的竖线代表s1,右边的竖线代表s2,上边的横线为h1, 下边的为h2
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; //n次 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; } } } } }
========================
两种方法及测试代码汇总如下:
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
- 小球在矩形框内45°碰撞问题
- 判断点是否在矩形内碰撞代码
- UVA10387矩形内的无损碰撞
- J2ME小球与砖的碰撞问题?
- 分离轴定理解决矩形碰撞问题
- 矩形碰撞
- 一个与小球碰撞有关的有趣问题
- 碰撞的小球
- JBox2D学习 - 小球碰撞
- HTML5+Javascript 小球碰撞
- HTML5小球物理碰撞
- java小球弹性碰撞
- flash小球碰撞
- Java版小球碰撞
- Java版小球碰撞
- 碰撞的小球 HTML5
- java碰撞小球
- 小球定时碰撞
- char数组的sizeof
- 剑指offer(二)java
- nyoj2-括号配对问题
- The Solution to LeetCode 15 3Sum改进版
- spring 定时任务cron在线表达式生成
- 小球在矩形框内45°碰撞问题
- Web窗体中的@page指令中各个字段的意思
- python3.6 sqlalchemy安装与使用
- 解决UnicodeEncodeError: 'ascii' codec can't encode characters in position 转自:http://cooler1217.iteye.c
- Python使用difflib对比两个文件操作实例
- 一个简单的登录,POST表单提交时报错,403 bad or missing token!
- Ubuntu中Vmware Tools的安装与卸载 <一>
- JavaScript写出,用户输入一个三位数,求出各个数位的和。
- hibernate知识点回顾