由于要写一个模拟多个小球相互碰撞的程序,所以我就研究了下两个小球相互碰撞之后的速度变化规律(理想环境下无摩擦无碰撞损耗等的完全弹性碰撞)。
我们都知道,两个小球如果是在同一条直线上相向而行,则我们可以通过能量守恒(动能守恒)和动量守恒来计算碰撞之后的速度,若两小球质量相等,则交换它们的速度。若质量不相等,则可以求出:
设两小球的质量为m1,m2,碰撞前速度为v1,v2,碰撞后速度为v'1,v'2。
则有以下两个公式同时成立:
m1 * v1 + m2 * v2 = m1 * v'1 + m2 * v'2 ---------------------------------------------------------------------(1)
1/2 * m1 * v1^2 + 1/2 * m2 * v2^2 = 1/2 * m1 * v'1^2 + 1/2 * m2 * v'2^2 -----------------------------(2)
(1)、(2)可化为:
m1 * v1 - m1 * v'1 = m2 * v'2 - m2 * v2 ----------------------------------------------------------------------(3)
1/2 * m1 * v1^2 - 1/2 * m1 * v'1^2 = 1/2 * m2 * v'2^2 - 1/2 * m2 * v2^2 -----------------------------(4)
(4)/(3)得:
v1 + v'1 = v2 + v'2 -------------------------------------------------------------------------------------------------(5)
(1)、(5)可化为:
m2 * v'2 = m1 * v1 + m2 * v2 - m1 * v'1 ---------------------------------------------------------------------(6)
v'2 = v1 + v'1 - v2 --------------------------------------------------------------------------------------------------(7)
把(7)代入(6)得:
m2 * v1 + m2 * v'1 - m2 * v2 = m1 * v1 + m2 * v2 - m1 * v'1 -------------------------------------------(8)
由(8)化简得:
v'1 = [ 2 * m2 * v2 + ( m1 - m2 ) * v1 ] / ( m1 + m2 )
同理可得:
v'2 = [ 2 * m1 * v1 + ( m2 - m1 ) * v2 ] / ( m1 + m2 )
这样就计算出碰撞后两小球的速度了。
但是,两小球能在同一直线上相向而行的概率基本为零,最常发生的碰撞则是这样的:
所以,我们得想办法把这样的碰撞情况转化为我们会处理的情况,加以计算。
那么我们来分析一下:
两小球的碰撞点在两球心的连线上,那么在理想状态下,两小球的相互作用力应该是沿着两球心的连线方向的。
根据牛顿第一定律,力是改变屋里运动状态的唯一原因,既然在垂直于两球心的连线的方向上没有力的作用,那么两小球在垂直于两球心的连线的方向上的分运动是不变的。
这样的话,两小球在垂直于两球心的连线的方向上的速度是不变的,那么同样这个方向上的动量和动能也是不变的。
那么,两小球在两球心的连线方向的分运动也遵循动量守恒和动能守恒。
这样,我们就能把一般碰撞事件转化为我们可以解决的在同一条直线上相向而行的碰撞事件来进行计算了。
现在,我们来分析一下分速度应该如何计算。
设小球速度为a,两球心连线为b,小球速度在两球心连线方向上的分速度为c,小球速度在垂直于两球心连线的方向上的分速度为d。
那么a · b = ( c + d ) · b = c · b + d · b。
而d与b相互垂直,所以d · b = 0。
那么a · b = c · b。
设b的斜率为k,那么可以再设a = ( x1, y1 ),b = ( x2, k · x2 ),c = ( x, k · x ),
那么代入得:
x1 · x2 + y1 · ( k · x2 ) = x · x2 + ( k · x ) · ( k · x2 )。
x = ( x1 · x2 + k · y1 · x2 ) / ( x2 + k^2 · x2 )
x = ( x1 + k · y1 ) / ( k^2 + 1 )
那么k · x为:
k · x = k · ( x1 + k · y1 ) / ( k^2 + 1 )
k · x = ( x1 + k · y1 ) / ( k + 1 / k )
现在回过头来,把这个公式代入小球的数据:
设碰撞时,小球1的速度为( v1x, v1y ),位置为( x1, y1 );小球2的速度为( v1x, v1y ),位置为( x2, y2 ),两球心连线方向的斜率为k。
那么小球1在两球心连线方向上的分速度v1_1,
它在x轴方向的分速度为:
v1_1x = ( v1x + k · v1y ) / ( k^2 + 1 )
它在x轴方向的分速度为:
v1_1y = k * v1_1x = ( v1x + k · v1y ) / ( k + 1 / k )
即:
v1_1 = ( ( v1x + k · v1y ) / ( k^2 + 1 ), ( v1x + k · v1y ) / ( k + 1 / k ) )
那么小球1在垂直于两球心连线的方向上的分速度v1_0,
它在x轴方向的分速度为:
v1_0x = v1x - v1_1x = v1x - ( v1x + k · v1y ) / ( k^2 + 1 )
它在x轴方向的分速度为:
v1_0y = v1y - v1_1y = v1y - ( v1x + k · v1y ) / ( k + 1 / k )
即:
v1_0 = ( v1x - ( v1x + k · v1y ) / ( k^2 + 1 ), v1y - ( v1x + k · v1y ) / ( k + 1 / k ) )
同理,小球2在两球心连线方向上的分速度为:
v2_1 = ( v2_1x, v2_1y ) = ( ( v2x + k · v2y ) / ( k^2 + 1 ), ( v2x + k · v2y ) / ( k + 1 / k ) )
小球2在垂直于两球心连线的方向上的分速度为:
v2_0 = ( v2_0x, v2_0y ) = ( v2x - ( v2x + k · v2y ) / ( k^2 + 1 ), v2y - ( v2x + k · v2y ) / ( k + 1 / k ) )
经过计算,我们可以得到碰撞后两小球在两球心连线方向上的分速度v_1_1,v_2_1。
那么碰撞后两小球的速度为v_1 = v1_0 + v_1_1,v_2 = v2_0 + v_2_1。
当然,若写成代码则不需要那么麻烦,只要定义几个中间变量,这些结果都可以由计算机计算(当然,下面的代码只是理想状况下的,因为线程的刷新是有间隔的,那么就会出现两小球边缘越过相切,达到相交的状态,解决这个问题还是相当简单的,自己去考虑吧。):
public void bumpEachother(Ball ball1, Ball ball2) { //获取两小球的质量 float m1 = ball1.getM(); float m2 = ball2.getM(); //获取两小球的位置 Point2D.Float position1 = ball1.getPosition(); Point2D.Float position2 = ball2.getPosition(); //获取两小球的速度 Point2D.Float velocity1 = ball1.getVelocity(); Point2D.Float velocity2 = ball2.getVelocity(); //定义碰撞后两小球的速度 Point2D.Float velocity_1 = new Point2D.Float(); Point2D.Float velocity_2 = new Point2D.Float(); //定义两小球在垂直于两球心连线的方向的速度 Point2D.Float velocity1_0 = new Point2D.Float(); Point2D.Float velocity2_0 = new Point2D.Float(); //定义碰撞前两小球在两球心连线方向的速度 Point2D.Float velocity1_1 = new Point2D.Float(); Point2D.Float velocity2_1 = new Point2D.Float(); //定义碰撞后两小球在两球心连线方向的速度 Point2D.Float velocity_1_1 = new Point2D.Float(); Point2D.Float velocity_2_1 = new Point2D.Float(); //定义两球心连线的斜率为k float k = (position1.y - position2.y) / (position1.x - position2.x); //计算碰撞前两小球在两球心连线方向的速度 velocity1_1.x = (velocity1.x + k * velocity1.y) / (1 + k * k); velocity1_1.y = k * velocity1_1.x; velocity2_1.x = (velocity2.x + k * velocity2.y) / (1 + k * k); velocity2_1.y = k * velocity2_1.x; //计算两小球在垂直于两球心连线的方向的速度 velocity1_0.x = velocity1.x - velocity1_1.x; velocity1_0.y = velocity1.y - velocity1_1.y; velocity2_0.x = velocity2.x - velocity2_1.x; velocity2_0.y = velocity2.y - velocity2_1.y; //计算碰撞后两小球在两球心连线方向的速度 velocity_1_1.x = (2 * m2 * velocity2_1.x + (m1 - m2) * velocity1_1.x) / (m1 + m2); velocity_1_1.y = (2 * m2 * velocity2_1.y + (m1 - m2) * velocity1_1.y) / (m1 + m2); velocity_2_1.x = (2 * m1 * velocity1_1.x + (m2 - m1) * velocity2_1.x) / (m1 + m2); velocity_2_1.y = (2 * m1 * velocity1_1.y + (m2 - m1) * velocity2_1.y) / (m1 + m2); //计算碰撞后两小球的速度 velocity_1.x = velocity1_0.x + velocity_1_1.x; velocity_1.y = velocity1_0.y + velocity_1_1.y; velocity_2.x = velocity2_0.x + velocity_2_1.x; velocity_2.y = velocity2_0.y + velocity_2_1.y; //重设两小球速度 ball1.setVelocity(velocity_1); ball2.setVelocity(velocity_2); }
好了,这样的话,两小球之间的相互碰撞事件的处理就完成啦,只要判断出两小球相撞,就可以调用这个类来改变小球速度啦~~
有人要Ball类的代码,我找了半天才找到,毕竟已经过了这么久了,不一定是一个版本的,不知道有没有问题……
import java.awt.Graphics2D; import java.awt.geom.Ellipse2D; import java.awt.geom.Point2D; /** * @author lolo * */ public class Ball { //小球半径 private float radius; //小球位置 private Point2D.Float position; //小球速度 private Point2D.Float velocity; //小球形状 private Ellipse2D.Float sphere; /** * 构造方法 * * @param radius the radius to set * @param density the density to set * @param position the position to set * @param velocity the velocity to set */ public Ball(float radius, float density, Point2D.Float position, Point2D.Float velocity) { this.radius = radius; this.position = position; this.velocity = velocity; this.sphere = new Ellipse2D.Float(0, 0, 2 * radius, 2 * radius); } /** * 绘制小球 * * @param g the Graphics2D which is used to draw */ public void drawBall(Graphics2D g){ sphere.x = position.x - radius; sphere.y = position.y - radius; g.fill(sphere); } /** * @return the radius */ public float getRadius() { return radius; } /** * @return the position */ public Point2D.Float getPosition() { return position; } /** * @param position the position to set */ public void setPosition(Point2D.Float position) { this.position = position; } /** * @param positionX the position.x to set */ public void setPositionX(float positionX) { this.position.x = positionX; } /** * @param positionY the position.y to set */ public void setPositionY(float positionY) { this.position.y = positionY; } /** * @return the velocity */ public Point2D.Float getVelocity() { return velocity; } /** * @param velocity the velocity to set */ public void setVelocity(Point2D.Float velocity) { this.velocity = velocity; } /** * @param velocityX the velocity.x to set */ public void setVelocityX(float velocityX) { this.velocity.x = velocityX; } /** * @param velocityY the velocity.y to set */ public void setVelocityY(float velocityY) { this.velocity.y = velocityY; } }
相关推荐
为了实现碰撞检测,程序可能使用了某种形式的空间分区算法,如格子法或者四叉树,以便高效地找出可能相撞的小球对。一旦找到可能的碰撞,就需要用到碰撞响应算法来计算碰撞后的速度。这个过程可能涉及到复杂的数学,...
- **碰撞响应**:当检测到碰撞发生时,对这些图形对象进行相应的物理行为调整,例如改变速度、方向等。 - **物理引擎**:一种软件库,用于处理游戏中物体的物理运动和交互,包括碰撞检测与响应。 #### 2. 碰撞检测...
通过对小球碰撞的研究,我们可以深入了解动量守恒和能量守恒定律的应用。在实际应用中,这些原理不仅可以帮助我们更好地理解物理现象,还可以为开发物理引擎、模拟软件等提供理论基础和技术支持。
总结,实现小球碰撞的C语言程序涉及对物理学的理解、结构体的使用、碰撞检测和碰撞后速度计算。通过这样的程序,你可以学习到C语言编程技巧,以及如何将物理原理应用于实际编程中。这是一个很好的练习项目,有助于...
在本示例中,我们将重点研究两种情况:单个小球在方框内的完全弹性碰撞和三个小球在相同环境下的碰撞。 首先,我们来看单个小球的碰撞模拟。完全弹性碰撞是指碰撞过程中动能和动量都得到完全保持的碰撞类型。在...
在"Ball_impact.rar"这个压缩包中,包含两个MATLAB脚本文件:"Ball_impact.m"和"a.m",它们用于实现对四个小球在限定区域内相互碰撞的动态模拟。 小球碰撞的物理过程涉及到动量守恒定律,这是物理学中的基本原理之...
在小球类中,`draw()`方法用于绘制小球,而`update()`方法则更新小球的位置,同时处理边界反弹。 接着,我们可以创建多个小球实例,并在每一帧中更新它们的状态并绘制到画布上: ```javascript let balls = []; /...
在本MATLAB建模仿真案例“30多个小球碰撞模拟”中,我们将深入探讨如何利用MATLAB强大的计算和可视化功能来模拟复杂物理现象。这个案例涵盖了基础的物理学原理、编程技巧以及MATLAB的Simulink环境应用。下面将详细...
这个"HTML5相互碰撞散开的小球"项目,是利用HTML5的Canvas元素和JavaScript实现的一个动态视觉效果。Canvas是HTML5中用于图形绘制的画布,通过JavaScript可以动态地在Canvas上绘制图形,实现丰富的动画效果。 在这...
在"HTML5相互碰撞散开的小球.zip"这个压缩包中,我们可以找到一个运用HTML5技术实现的动态效果,即小球碰撞后散开的特效。这种特效能够为网站增加视觉吸引力,提升用户体验。 首先,`index.html`是网页的主文件,它...
总结来说,这个"Small-Ball-Collision-master"压缩包提供了一个用JavaScript实现的小球碰撞特效,涉及到的关键知识点有:JavaScript动画处理、碰撞检测算法、向量运算、事件处理以及可能的HTML/CSS组合。这个项目...
4. 多小球碰撞:处理多个小球相互碰撞的情况,需要避免重复检测和处理。 5. 固定边界碰撞:除了小球之间的碰撞,还要考虑小球与环境边界(如屏幕边缘)的碰撞。 在提供的压缩包文件中,"Win32SDKDemo"可能是使用Win...
- 对心碰撞:两物体碰撞时,碰撞前后运动方向都在同一直线上,这种碰撞称为对心碰撞,也称为正碰。 - 非对心碰撞:如果碰撞前后物体的运动方向不在同一条直线上,这种碰撞被称为非对心碰撞或斜碰。 5. 散射:在...
在具体问题解决中,例如光滑水平面上三个小球的碰撞,由于碰撞的瞬时性,中间的小球在第一次碰撞中不会对第三个球产生影响。这意味着可以分别处理每个连续的碰撞,利用动量守恒定律找到碰撞后各个物体的速度。 另一...
5. 此实验中,绳的张力对小球是否做功?为什么? 6. 定量导出本实验中碰撞时传递的能量 e 和总能量 E 的比?=e/E 与两球质量比? =m1/m2 的关系。 7. 本实验中,球体不用金属,用石蜡或软木可以吗?为什么?
物理学中关于碰撞的研究,不仅是力学部分的一个重点,也是工科领域和诸多运动中不可或缺的理论基础。本文将对碰撞进行深入探讨,特别关注在碰撞过程中功和能的转换原理。 首先,碰撞按照不同特征可分为两大类型:对...
《小球快跑》是一款基于Android平台的3D物理传感游戏,它充分利用了Android系统对3D图形处理和物理感应技术的支持,为玩家提供了一种全新的互动体验。本游戏是Android2.0游戏开发实战宝典中的一个典型实例,旨在展示...
通过对二维平面碰撞的研究,我们可以更好地理解和模拟现实世界中的碰撞现象。动量守恒定律是解决这类问题的关键,它不仅适用于简单的碰撞场景,还可以扩展到更复杂的多体碰撞问题中。通过准确地计算碰撞冲量和恢复...
在碰撞模型中,两个物体在相互作用时,会出现“速度相等”的情况。此时,两个物体的速度必定相等,具体分析如下: 1. 光滑水平面上的 A 物体以速度 v 去撞击静止的 B 物体,A、B 两物体相距最近时,两物体速度必定...
在探索物理世界的奥秘中,碰撞现象是一个极其重要而又常见的现象,无论是日常生活中的简单碰撞,还是宇宙空间中星体之间的相互作用,碰撞的研究对于我们理解物质世界的运动规律至关重要。在物理选修35的课程中,碰撞...