取自2017年自己写的一篇文章
canvas绘图是H5规范中有关绘图规范的一种强大的武器,可用于生成各种逻辑动态图,产生很多酷炫的效果。canvas动画的本质是帧图片连续播放,通过快速切换“图片”,达到“欺骗”眼睛视觉暂留产生流畅动画的效果,人眼的分辨极限是24帧1秒,有关视觉暂留原理,可自行百度。所以canvas绘图的关键是记录不同时刻要绘制的图案的位置以及图案位置之间的逻辑关系。
在canvas动态绘图中经常遇到物体之间发生碰撞的需求,这种碰撞需要尽可能还原真实场景,这其中就蕴含了一定的物理知识与数学计算知识,有的还包含计算图形学,离散数学等等知识。这篇文章以圆形粒子碰撞为例,结合物理知识来说明该类问题的解决方案。
粒子碰撞后的状态求解,本文总结三种解决模型:
- 1.动量简易处理模型
- 2.动量详细处理模型
- 3.弹簧(弹动)处理模型
这三种模型都假设:- 1.小球都是半径为R的圆;
- 2.小球表面是光滑的;
- 3.小球之间的碰撞为弹性碰撞(没有能量损失),与canvas画布“四周”的碰撞可以设定弹性碰撞(例如反弹系数设为-1)和非弹性碰撞(例如反弹系数设为-0.95);
1.动量简易处理模型
模型运用到的知识点是:
a.同等质量的小球对心碰撞时候,速度交换,物理依据是X轴与Y轴动量守恒。
物理学公式遵循x轴方向与y轴动量守恒,提醒:这个简化模型是有缺陷的。
当m1=m2的时候,就可以实现x,y两个方向上速度的互换.
演示效果如下:
这种简化模型实现的效果并不好,在速度较小的情况下还不明显;但是在速度较大的情况下,小球之间很容易有重叠部分,并一直缠绕,用于演示还行,实战不推荐这种做法
2.动量详细处理模型
模型运用到的知识点有:
1.水平方向与垂直方向动量守恒;
2.以两球相切面做坐标系转换,球心连线方向动量守恒,垂直于球心连线方向速度不变(可以带质量)
注:左上为球1,右下为球2
物理学公式如下:
动量守恒公式可以分解为水平和垂直方向的两个部分:
沿水平方向:
沿垂直方向:
demo2如下:
这种模型比第一种要更加完善一些,看起来更加流畅,比较更加符合物理定律,虽然还不是完全符合,对于物理学上的小球“斜碰问题”是一个比较复杂的研究课题,考虑的因素众多,有兴趣的可以参考文献《弹性小球斜碰的散射角_柯坤章》(没给链接,百度学术或中国知网可以下载)
3.弹簧(弹动)处理模型
模型应用到的知识点有:
1.弹簧的运动,平衡位置(一般设置为目标位置)速度最大,加速度最小(为零);
2、位移最大处速度最小,加速度最大,加速度与目标位置与物体位置的差值成正比,本方法将小球接触面想象成弹簧。
这个就不贴物理示意图和公式了,下面举个简单例子说明弹簧的“弹动”
上面演示了弹动的例子,意思就是加速度与物体位移及目标位移的差值成正比,加速度影响速度,速度影响物体位移,就这样的一个反馈系统。
注:上述demo也可以演示“缓动”,即速度与物体位移及目标位移的差值成正比,最终停止,是一个“先快后慢,最后停止”的过程,感兴趣的童鞋可以也去研究下
“弹动”应用到小球碰撞的例子中,关键的就是找到目标位置,也就是相当于“弹簧”松弛状态下的位置,该例中,目标位置是两个球刚好接触的位置(两球相交,球心之间的最远距离即是这个) demo如下:
注:1.缓动系数spring 要注意,不能过大 ,否则,小球在一个刷新周期内就跑到canvas画布外面很远了,效果变差;
2.看的出来两个球接触的时候,会进入对方一点距离,这就是将小球当做弹簧来处理的效果,稍微调大spring ,减小速度和小球半径,可以减少这种不适感;
3.例子中有“ 如果两个小球位置有重叠的解决办法”的部分可以省略,这只是一种优化手段,增强效果。
总结:1.上述三种方法最好使用的第二种,可以做出比较绚丽的图案,第三种效果也还可以,处理起来公式比较简单,第一种就比较简陋,常用作演示;
2.本文涉及到小球碰撞检测,比较的是两个小球的圆心之间的距离与两小球半径之和的差值,小于0即发生碰撞,反之没有发生碰撞;检测方法还可以拓展到矩形检测和像素检测,这些在具体的应用当中都有涉及,可以再研究;
3.本文只是做一些js原生的canvas方法总结,有很多优秀的canvas库,可以制作非常优秀的动画以及游戏,如create.js等等,这些类库都非常强大,应用很广泛;
4.canvas作为js两个方向之一—-偏设计类的重头戏,可以深入研究研究,毕竟动画对于改善用户体验的作用是显而易见的。