19、《每周一点canvas动画》——桌球运动(1)

33人阅读 评论(1) 收藏 举报
分类:

每周一点canvas动画代码文件

一本好的技术书籍往往都是由浅入深,本系列文章基本上也遵循这个原理。在上一章中我们介绍了高级的坐标旋转,并且通过它,我们实现了任意角度的碰撞反弹效果,它让物体与非水平和非垂直的面产生合乎情理的碰撞成为了可能。那么在本章我们继续深入的介绍另一个问题——物体与物体发生碰撞后应该如何处理?

也许你会说,在前面的章节中我们不是已经介绍过物体与物体之间的碰撞检测了吗?但是细细想来,其实我们只是完成了一个碰撞检测的前半部分,那么碰撞后的效果该如何处理呢?

在以前的动画中,我们对碰撞后的处理很简单,很暴力。首先是,设定位置。其次,水平和竖直方向分别乘以反弹系数(bounce)。是不是太简约,太粗暴了点。

那么,真实世界中,两个物体发生碰撞的情况是什么样呢?物体的重量不一样,速度不一样,运行方向不一样。如果发生了碰撞,之后他们的运动轨迹,速度大小可不是我们简单的乘以反弹系数就能解决的。

说了这么多的废话,本章的核心就是:如何处理物体发生碰撞后的运动,提前预告本章要用到的新的物理概念有:

  1. 动量

  2. 动量守恒

  3. 能量守恒

1.什么是动量

百度百科上这样说

动量(Momentum)又称线性动量(Linear Momentum)。在经典力学中,动量(是指国际单位制中的单位为kg·m/s ,量纲MLT⁻¹)表示为物体的质量和速度的乘积,是与物体的质量和速度相关的物理量,指的是运动物体的作用效果。动量也是矢量,它的方向与速度的方向相同

如果,你对中学的物理知识还有印象,那么这个概念应该很好理解。甚至可以轻松的写出动量的表达式

动量(p), 质量(m), 速度(v)

表达式: p = m * v

也就是说,动量是物体质量与速度的乘积

2.动量守恒

动量守恒:如果一个系统不受外力或所受外力的矢量和为零,那么这个系统的总动量保持不变,这个结论叫做动量守恒定律

简单点来说就是,物体1与物体2如果发生碰撞,那么他们碰撞前的动量大小之和与碰撞后的动量大小之和是以不变的。

假设,物体1的质量为m1, 运动速度为v1, 碰撞后的速度v1F。物体2的质量为m2, 运动速度为v2, 碰撞后的速度v2F。 那么,他们满足

 m1 * v1 + m2 * v2 = m1 * v1F + m2 * v2F

是不是很熟悉?当然这一个公式有两个未知数,是没法解出碰撞后的速度v1F和v2F的。这时候就需要能量守恒出场了。

3.能量守恒

这个概念相对来说很简单。物体以一定的速度运动,那么它的能量为多少呢?

E = 0.5 * m * v^2

同时,也有个能量守恒的规律,与动量守恒的描述相似。两物体如果发生碰撞,那么前后的能量保持不变。

 (0.5 * m1 * v1^2) + (0.5 * m2 * v2^2) = (0.5 * m1 * v1F^2) + (0.5 * m2 * v2F^2)

ok,有了上面两个公式,我们就可以解出碰撞后的速度

公式1: m1 * v1 + m2 * v2 = m1 * v1F + m2 * v2F
公式2: (0.5 * m1 * v1^2) + (0.5 * m2 * v2^2) = (0.5 * m1 * v1F^2) + (0.5 * m2 * v2F^2)

解得,碰撞后的速度为

v1F = ((m1 - m2)*v1 + 2*m2*v2) / (m1+m2)
v2F = ((m2 - m1)*v2 + 2*m1*v1) / (m1+m2)

总结一句话:出来混总是要还的

4.代码实例

那么怎样把上面的内容应用到代码中呢。这里我们采用球类文件ball.js。在上面加一行代码

this.mass = 1;

也就是设定球的初始质量为1,这就ok了,就是这么简单。然后我们先来水平方向的,先看效果图

具体代码如下:

<canvas id="canvas" width="500" height="500" style="background:#000">
       <p>your browser not support canvas</p>
   </canvas>
   <script src="../js/utils.js"></script>
   <script src="../js/ball.js"></script>
   <script>
     window.onload = function(){
       var canvas = document.querySelector('canvas'),
           context = canvas.getContext('2d'),
           ball0 = new Ball(),
           ball1 = new Ball(20,"red");

            //球0
            ball0.mass = 2;                  //质量为2
            ball0.x = 50;
            ball0.y = canvas.height/2;
            ball0.vx = 1;

            //球1
            ball1.mass = 1;                    //质量为1
            ball1.x = 400;
            ball1.y = canvas.height/2;
            ball1.vx = -1;                    //速度为反向,大小为1

            (function drawFrame(){
                window.requestAnimationFrame(drawFrame, canvas);
                context.clearRect(0, 0, canvas.width, canvas.height);

                ball0.x += ball0.vx;
                ball1.x += ball1.vx;

                var dist = ball1.x - ball0.x;

            if(Math.abs(dist) < ball0.radius + ball1.radius){ //碰撞检测
                //计算碰撞后的速度
                var vx0Final = ((ball0.mass - ball1.mass)*ball0.vx + 2 * ball1.mass * ball1.vx)/(ball0.mass +ball1.mass);
                var vx1Final = ((ball1.mass - ball0.mass)*ball1.vx + 2 * ball0.mass * ball0.vx)/(ball0.mass +ball1.mass);

                //控制台打印
                console.log(vx0Final, vx1Final);

                //重新赋值
                ball0.vx = vx0Final;
                ball1.vx = vx1Final;

                ball0.x += ball0.vx;
                ball1.x += ball1.vx;
            }

                ball0.draw(context);
                ball1.draw(context);
            }())
        }
   </script>

在上面的代码中,我把碰撞后的代码在控制台打印出来。

带入公式算算,是否满足动量守恒。如果我们把球1的质量该的大一点呢?

    ball0.mass = 3; 

再看看效果

球1碰撞后的速度几乎为0,感觉是不是与自己的体型成正比啊。那么如果我们加大球2的速度呢?

    ball1.vx = -3;

效果如下

难道这就是传说中的小身材大力量吗!更多的效果可以去自己尝试。

这节的内容就到这里了,主要是些基础概念性的东西。下一节,按照惯列就开始逐渐深入了,敬请期待。

查看评论

深入 WIN2000 组册表 (3)

                 测某个计算机管理Snap-In是否可用尽管M i c r o s o f t提供了一组重要的M M C工具,但是为Windows 2000提供服务应用程序的供应商通常...
  • coolstar
  • coolstar
  • 2001-08-01 13:37:00
  • 1110

8、《每周一点canvas动画》——边界检测与摩擦力(2)

到目前为止,我们最常见的两种情形: 物体按照一定的速度做任意运动直到碰上边界 物体自身,或者通过外部的作用力,运用加速度来改变物体的速度 不管怎样,除非我们...
  • qq_39759115
  • qq_39759115
  • 2018-01-03 09:56:51
  • 91

11、《每周一点canvas动画》 —— 弹性动画

本系列文章代码文件 在上一章我们介绍了缓动动画,并且对弹性动画的概念做了简单的介绍。弹性动画(spring)与缓动动画都是基于距离的百分比动画,两者的不同之处在于,一个作用于速度(ease), ...
  • qq_39759115
  • qq_39759115
  • 2018-01-15 17:20:02
  • 100

7、《每周一点canvas动画》——边界检测与摩擦力(1)

本章已经是《Canvas 动画系列》动画的第七篇了,我保证这一章不会再有难的数学公式和物理概念。鉴于有的同学并不是从第一章开始看这个系列,我将会把本文所用到的一些 类...
  • qq_39759115
  • qq_39759115
  • 2018-01-02 11:49:18
  • 119

20、《每周一点canvas动画》——桌球运动(2)

每周一点canvas动画代码文件 在上一节,《每周一点canvas动画》——桌球运动(1)中我们介绍了如何运用动量守恒和能量守恒的概念,最为真实的模拟了物体与物体之间发生碰撞后的情况。那么这...
  • qq_39759115
  • qq_39759115
  • 2018-04-17 11:15:52
  • 28

Html5系列(二十三) canvas高级贝塞尔曲线运动动画

DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1...
  • dhdhxgx
  • dhdhxgx
  • 2015-04-16 23:05:31
  • 5742

Canvas5——路劲应用绘制动画效果初级

Information 利用Canvas路径api绘制线与圆,让圆沿着线的方向运动。实现原理很简单,就是不断的清楚画布,然后再重新绘制各个组件。当然,这个逻辑也是制作大部分动画的根本逻辑。 有...
  • tangxiaolang101
  • tangxiaolang101
  • 2016-05-18 17:15:01
  • 601

4.每周一点canvas动画--波形运动

在上一节我们介绍了canvas动画中有关三角函数的内容,以及一个跟随鼠标旋转的箭头动画。这一节主要介绍三角函数的波形运动。包括: 平滑运动 线性运动 脉冲运动 1.Sin函数的波形sin函数的波形想必...
  • qq_39759115
  • qq_39759115
  • 2018-01-02 11:40:30
  • 72

14、《每周一点canvas动画》——碰撞检测(1)

每周一点canvas动画代码文件 在前面的几章中我介绍了一些动画效果,这些动画效果都相对基础。但是通过这些基础的动画形式和概念,你可以设计出更复杂的动画。本章将介绍在动画中相对来说比较难的物理概...
  • qq_39759115
  • qq_39759115
  • 2018-01-15 17:22:53
  • 114
    个人资料
    持之以恒
    等级:
    访问量: 1万+
    积分: 787
    排名: 6万+
    最新评论