码迷,mamicode.com
首页 > 编程语言 > 详细

二维非对心弹性碰撞的算法

时间:2018-05-16 20:52:44      阅读:332      评论:0      收藏:0      [点我收藏+]

标签:利用   SQ   sqrt   his   算法   理解   typos   ext   非对心碰撞   

该算法适合常见的二维完全弹性碰撞的场合,支持对心碰撞(正碰)和非对心碰撞(斜碰),不考虑碰撞过程中的机械能损耗,不考虑物体表面摩擦以及恢复系数。


/*
* this是自身对象,sp是碰撞的对象
* this.m   质量
* this.r   半径
* this.vx  水平速度
* this.vy  竖直速度
* 为了便于理解,代码未经优化!
*/

collide(sp) {
    if (this.isCollideWith(sp)) {
        
        // 利用弹性碰撞公式计算水平、竖直方向上的速度分量 let vx
= this.vx let vy = this.vy this.vx = ((this.m - sp.m) * this.vx + 2 * sp.m * sp.vx) / (this.m + sp.m) this.vy = ((this.m - sp.m) * this.vy + 2 * sp.m * sp.vy) / (this.m + sp.m) sp.vx = (2 * this.m * vx + (sp.m - this.m) * sp.vx) / (this.m + sp.m) sp.vy = (2 * this.m * vy + (sp.m - this.m) * sp.vy) / (this.m + sp.m)
        // 关键!在速度突变的情况下(例如碰壁反弹,或者另一物体被挤压以至于无法移动),必须防止位置重叠的情况出现
        // nextXPos和nextYPos是提前判断二者下一帧的位置。若下一帧位置重叠,则反弹。 let ax
= this.nextXPos() let ay = this.nextYPos() let bx = sp.nextXPos() let by = sp.nextYPos() if (Math.sqrt((ax - bx) ** 2 + (ay - by) ** 2) < (this.r + sp.r)) { let agl = 0  // 反弹方向相对屏幕坐标系的角度 if (this.x != sp.x) agl = Math.atan((this.y - sp.y) / (this.x - sp.x))
          // 反弹的速度的方向需根据二者位置来确定 let v
= Math.sqrt(this.vx ** 2 + this.vy ** 2) this.vx = v * Math.cos(agl) * (this.x > sp.x ? 1 : -1) this.vy = v * Math.sin(agl) * (this.y > sp.y ? 1 : -1) v = Math.sqrt(sp.vx ** 2 + sp.vy ** 2) sp.vx = v * Math.cos(agl) * (sp.x > this.x ? 1 : -1) sp.vy = v * Math.sin(agl) * (sp.y > this.y ? 1 : -1)} }

二维非对心弹性碰撞的算法

标签:利用   SQ   sqrt   his   算法   理解   typos   ext   非对心碰撞   

原文地址:https://www.cnblogs.com/mygodfalling/p/9047590.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!