如何用代码实现一个黑洞效果?| 技术头条

2019 年 4 月 11 日 CSDN

者 | 叶斋

本文来源于阿里巴巴前端技术专家叶斋在内网的「如何实现某些动画」的系列分享,该系列分享包括如何用代码实现爆炸、黑洞、蜘蛛、扫描等,阿里巴巴中间件受权发布。

因为对动画比较了解的缘故,团队的其他同学时常会找我讨论「如何实现某些动画」,在与同学们的交流过程中,我发现,对大部分前端工程师而言,编写前端动画的难度并不在前端技术本身,而是对动画背后的规律缺乏理解,在尝试用数学语言表达动画时感到困难。

所以,在入门动画的过程中,往往出现这样的情况:即虽然对动画相关的 API 了如指掌,但是一旦遇到实际问题,就显得缺乏思路,无从下手。

其实,掌握动画规律并不困难,甚至可以说是极为简单。而实现各种各样的粒子系统,是一种很好的锻炼动画思路的实践。为此,我尝试推出一个的博文系列「每日一则粒子效果」,每篇文章分析一个简单的小例子,希望能够帮助到大家。

这一篇,我们来看看如何用代码实现一个黑洞效果。

黑洞效果:其实就是粒子一边旋转一边靠近(被吸过去)中心点。在这个粒子中,我们使用极坐标(theta, r)来代替直角坐标(x,y)描述一个点的位置。

坐标用来描述点,其含义是,唯一的坐标可以确定唯一的点。在直角坐标中,根据(x,y)两个坐标值就可以(无需其他任何信息)确定该点的位置,而在极坐标下,同样根据(theta, r)两个坐标值,也可以(无需其他任何信息)确定该点的位置。极坐标和直角坐标之间可以进行转化,如图所示:x = r * cos(theta),y = r * sin(theta)。

这个模型中需要注意的是:在直觉上,黑洞效果的一个显著特点,就是粒子被吸入进去的时候,其速度是越来越快的,当粒子比较接近黑洞中心的时候,粒子是以非常快的速度旋转和逼近黑洞中心,然后消失。这其实与我们所学习的能量守恒定律有类似之处,当粒子越来越靠近黑洞,其旋转半径越来越小,势能就转化为了动能,所以粒子的线速度就越来越快。利用这「近似的能量守恒」,就可以制作出比较逼真的黑洞效果了。

在初始化的时候,为每个粒子生成随机的极坐标 theta 和 radius,然后生成限定在特定区间内的随机速度。

这里需要注意的是,radius 和 speed 需要在特定区间内,才能有比较好的效果,如果粒子的速度过快或半径过大,在真实环境下是可能逃离黑洞的,制作动画时强行使其被吸入黑洞,会使动画的效果打折。

points.push({
  ...
  theta: Math.random() * Math.PI * 2,
  radius: RADIUS * (Math.random() * 0.5 + 0.1),
  speed: SPEED * (Math.random() * 0.6 + 0.2)
})

每一帧粒子位置的逻辑如下:

var theta = p.theta;
var radius = p.radius;
var speed = p.speed;

var dTheta = speed * step / radius;
var dRadius = (8000 / (radius * radius) - speed * speed) * step / 10;
var dSpeed = Math.sqrt(dRadius) / 500;

p.theta += dTheta;
p.radius -= dRadius;
p.speed += dSpeed;
  • 极坐标角度值 theta  的增量,即旋转过的角度,是粒子的速度乘以时间除以半径得到。

  • 极坐标半径值 radius 的增量,与引力和离心力的差有关。引力与半径的平方成反比,离心力与速度的平方有关系。

  • 粒子速度的增量与半径增量的开方成正比。

上述模型也只是真实世界的粗糙模拟,比如第二条,引力与离心力的差其实影响的是坠落的加速度,我们简单地使之与速度正相关;又比如第三条中速度增量与半径增量开放成正比,其实只适用于引力不变的情况,这时候就不得不配合一些「神奇数」调试出合适的效果。

反复调试代码中的一些常量,直到效果满足我们的预期。

源代码地址:

https://xieguanglei.github.io/particles-day-by-day/pages/day4-better-blackhole/index.js

作者:谢光磊(花名:叶斋),阿里巴巴前端技术专家,专注于前端图形渲染领域的架构和开发工作。《WebGL 编程指南》译者,开源 WebGL 3D 引擎 G3D 核心开发者。

声明:本文为公众号阿里巴巴中间件投稿,版权归其所有。

【End】

 热 文 推 荐 

戳他↓↓↓

☞京东“地震”

☞掌握 Android 系统架构,看这一篇就够了!| 技术头条

漫画:如何给女朋友解释什么是乐观锁与悲观锁 | 技术头条

☞频繁跳槽涨工资?会影响征信的! | 畅言

☞39个国外SCI抢发6万篇中国英文论文?然而,真正的问题是……

☞偷电、挖矿、赚快钱,这些大学生到底怎么了?

终于有人把5G和边缘计算的关系说清楚了  | 技术头条

☞程序员为什么都爱穿冲锋衣?(最全总结)

System.out.println("点个在看吧!");
console.log("点个在看吧!");
print("点个在看吧!");
printf("点个在看吧!\n");
cout << "点个在看吧!" << endl;
Console.WriteLine("点个在看吧!");
Response.Write("点个在看吧!");
alert("点个在看吧!")
echo "点个在看吧!"

点击阅读原文,输入关键词,即可搜索您想要的 CSDN 文章。

你点的每个“在看”,我都认真当成了喜欢
登录查看更多
0

相关内容

阿里巴巴集团于1999年创立,阿里巴巴集团子公司及关联公司有:阿里巴巴网络有限公司、淘宝网、淘宝商城(天猫)、一淘、支付宝、阿里云计算、中国雅虎等。
【干货书】数值计算C编程,319页pdf,Numerical C
专知会员服务
66+阅读 · 2020年4月7日
【Nature论文】深度网络中的梯度下降复杂度控制
专知会员服务
38+阅读 · 2020年3月9日
《代码整洁之道》:5大基本要点
专知会员服务
49+阅读 · 2020年3月3日
【GitHub实战】Pytorch实现的小样本逼真的视频到视频转换
专知会员服务
35+阅读 · 2019年12月15日
【书籍】深度学习框架:PyTorch入门与实践(附代码)
专知会员服务
160+阅读 · 2019年10月28日
教你实现超流行的骨架屏预加载动态效果
IMWeb前端社区
71+阅读 · 2018年11月27日
拔刺 | 如何通过人工神经网络实现图像识别?
10道题,测一测你的AI水平到底如何
七月在线实验室
8+阅读 · 2018年7月17日
基于Numpy实现神经网络:反向传播
论智
5+阅读 · 2018年3月21日
干货:10 种机器学习算法的要点(附 Python代码)
全球人工智能
4+阅读 · 2018年1月5日
如何用 RNN 实现语音识别?| 分享总结
AI研习社
3+阅读 · 2017年12月15日
脑机接口技术如何具体实现?
人工智能学家
7+阅读 · 2017年12月7日
循环神经网络的介绍、代码及实现
AI研习社
3+阅读 · 2017年11月21日
Directions for Explainable Knowledge-Enabled Systems
Arxiv
26+阅读 · 2020年3月17日
Meta-Learning to Cluster
Arxiv
17+阅读 · 2019年10月30日
Arxiv
5+阅读 · 2018年1月30日
VIP会员
相关VIP内容
【干货书】数值计算C编程,319页pdf,Numerical C
专知会员服务
66+阅读 · 2020年4月7日
【Nature论文】深度网络中的梯度下降复杂度控制
专知会员服务
38+阅读 · 2020年3月9日
《代码整洁之道》:5大基本要点
专知会员服务
49+阅读 · 2020年3月3日
【GitHub实战】Pytorch实现的小样本逼真的视频到视频转换
专知会员服务
35+阅读 · 2019年12月15日
【书籍】深度学习框架:PyTorch入门与实践(附代码)
专知会员服务
160+阅读 · 2019年10月28日
相关资讯
教你实现超流行的骨架屏预加载动态效果
IMWeb前端社区
71+阅读 · 2018年11月27日
拔刺 | 如何通过人工神经网络实现图像识别?
10道题,测一测你的AI水平到底如何
七月在线实验室
8+阅读 · 2018年7月17日
基于Numpy实现神经网络:反向传播
论智
5+阅读 · 2018年3月21日
干货:10 种机器学习算法的要点(附 Python代码)
全球人工智能
4+阅读 · 2018年1月5日
如何用 RNN 实现语音识别?| 分享总结
AI研习社
3+阅读 · 2017年12月15日
脑机接口技术如何具体实现?
人工智能学家
7+阅读 · 2017年12月7日
循环神经网络的介绍、代码及实现
AI研习社
3+阅读 · 2017年11月21日
Top
微信扫码咨询专知VIP会员