基于HTML5的动态线
来源:互联网 发布:网络缓存级别最高延迟 编辑:程序博客网 时间:2024/06/06 13:11
基于HTML5的动态线
1 起因
某天晚上在微信公众号中看到一篇令人上瘾的科学动图,我对这类实验十分感兴趣,但自己并不是科学工作者,所以也就仅限于感兴趣为止。
不过其中有一张地球和金星的运动轨迹,如下图:
我觉得这个我可以实现,于是就抽出时间自己做了个类似的小东西。
2 结构和思路
动图的结构是内外两个同心圆,两个动点分别在两个同心圆上运动,间隔一定的时间将两点连线,最后就能组成想要的图案了。
正因为思路和结构十分简单,我才觉得自己能够实现出来。
事实上确实很容易实现。
3 Canvas
HTML5的<canvas>
标签提供了绝好的画板,比自己实现BMP图像容易多了,而且可以通过JavaScript来做出动画效果。
我设置的画布是511×511的,这是为了让圆心在正中间,没有特殊的含义。
首先初始化成黑色。然后开始画图。
4 画线
在Canvas中改变某一点的颜色很容易。使用Canvas的经验得自于Milo Yip的用JavaScript玩转计算机图形学。
Color的代码也是借鉴他的实现方式,我也考虑了直接使用数组,但还是选择了使用更清晰的Color。
之后就是其他的组成元素,Point、Line和Circle。
画线是最难的。我自己写了一个画线的方法,用的就是最简单直观的算法。
根据起点和终点的坐标,和每条直线都是形如
由于并非每个Math.round()
,让直线看起来更平滑。
但这个做法并不完全起效。
我通过随机生成终点和起点坐标的方式来测试这种算法的效果,发现有些直线很合理,但也有一些不那么合理,直线变成了稀疏的点阵。
于是我搜索了一下一般的图形引擎中是如何实现画线算法的,得到了Bresenham算法。
在复刻这个算法之前,我也明白了为什么我的算法并不一直有效。
我曾经也写过画线的算法,遇到了和现在一样的问题。尽管当时没有解决,但是意识到了问题所在:由于像素本身是稀疏的点阵(没有小数坐标),所以每个
用更数学,或者更计算机科学一点的语言来说,就是当直线斜率的绝对值大于1时,一些x对应多个y值。
这时候需要将直线沿着
5 Bresenham算法
Bresenham算法是一组常用的图形算法之一,上边这个算法太过直观,所以实现起来虽然简单,但性能上有所欠缺。
Bresenham算法则使用另一种计算方式。
但画直线这种事情,无论怎么算,都是基于数学的,而数学上的一条直线就是一个一元一次函数。这一点没有变。
Bresenham算法更多的是将计算过程从浮点运算和除法运算变成了整数的加法。这一点对计算机的性能影响比较大——至少在早期,这种性能影响完全不能忽略。
通过
当已知直线上一点
这是很简单的计算。也就是说,横坐标每增加1,纵坐标需要增加斜率a。将这个增量称作误差,记作
就像最初的算法中为了保证直线的美观,使用到了Math.round()
函数,Bresenham算法也需要判断纵坐标何时需要加一。
那么当误差
当然,这样计算还是浮点计算,为了优化性能,需要将浮点计算变成整数计算。
在画线之前,我们已经知道了直线的起点和终点,设为
斜率则是
判断纵坐标加一的条件是
此时
这个值也不见得一定是整数,所以两侧再同乘以
经过这样的变换,
于是求新坐标的伪代码如下:
deltax = abs(x0 - x1)deltay = abs(y0 - y1)error = 0y = y0for x from x0 to x1, step = 1: error = error + deltay*2 if error > deltax: y = y + 1 error = 0
当然以上伪代码的前提是斜率在
我使用的JavaScript代码则来自StackOverflow社区上的一个答案。
Bresenham算法不仅包含了直线的画法,也包含了一些其他的图形,圆形当然也包括在内。所以我从某个博客上直接拿过来用了。
主要的思路是将一个圆分成八份,每次计算坐标可以画出8个点。
但其中计算使用了一些常数,这些常数的来历我没有仔细看,但博客中应该写到了。
6 运动的圆形
为了显示出来金星和地球,多加了两个实心圆形。这两个圆形就不是用canvas画出来的了。
如果使用canvas画,需要记录每次移动前的圆形内部的像素数据,虽然不是不能实现,但是很麻烦。
所以直接用两个<div>
代替。使用两个<div>
,通过绝对定位就可以使之浮现在canvas上方。在通过计算坐标,使其与动点的坐标一致就可以了。
后来又加入了一些可以设定运动参数的功能,都只是锦上添花的小东西,不做赘述了。
7 效果
最后附上效果链接:
转动的同心圆
有了以上链接,代码就不贴了。
PS. 啊,差点把初衷忘了。要想画出和动图中相似的图案,我找到的最接近的参数应该是Inner speed = 6.5, Outer speed = 4
,起点都是270
。
- 基于HTML5的动态线
- RGraph-基于HTML5的 JavaScript 动态仪表盘
- RGraph-基于HTML5的 JavaScript 动态仪表盘
- RGraph-基于HTML5的 JavaScript 动态仪表盘
- 基于HTML5的canvas对象开发的动态连连看
- 基于HTML5的js构造爱心,动态时间校准
- 基于HTML5 Canvas的3D动态Chart图表
- 基于HTML5的表单
- 基于html5的画板程序
- 基于HTML5的图表分析
- 基于Html5的游戏框架
- 基于HTML5的汽车中间件
- 2.基于html5的模板
- 基于Html5的android开发
- 基于Html5的文件上传
- 基于HTML5 Canvas的引擎
- 基于HTML5的五子棋游戏
- 基于html5的五子棋游戏
- 深度学习算法之YOLOv2
- No ip domain-lookup和Logging synchronous和Exec-timeout 0 0
- Jmeter 使用集
- Mbean
- 2815:城堡问题
- 基于HTML5的动态线
- Android view 自定义控件
- zabbix告警 磁盘inodes占用过多的问题
- 元素宽度的最大百分比
- Ubuntu下IDEA无法输入中文问题 解决方法
- .NET-object与Json(反)序列化,键提取
- 1057. Stack (30)
- 如何在没有实际项目经验的情况下找到工作
- 返回第n个无平方数因数的数