在文章的开头,我们先来认识一下斐波那契数列
斐波那契数列 又被称作是 兔子数列
e.g. 1、1、2、3、5、8、13、21、34、…
从上面的例子可以看出斐波那契数列的规律,就是从第三个数开始,每个数的值都是它前两个数之和。
再来看一下例子程序:
function getFibonacci(n) {
let arr = []
let i = 0
while (i < n) {
if (i <= 1) {
arr.push(i)
}else {
arr.push(arr[i - 1] + arr[i - 2])
}
i++
}
return arr
}
知道了斐波那契数列 之后怎么用呢?今天来教你使用Canvas 来绘制斐波那契螺旋线。
我们要画的就是上图中的曲线。
现在开始贴代码,代码中的难点都带有注释。
let ctx = canvas.getContext('2d')
ctx.beginPath();
ctx.arc(300, 240, 5, Math.PI, 0.5 * Math.PI, true);
ctx.arc(300, 235, 10, Math.PI * 0.5, 0, true);
ctx.arc(295, 235, 15, 0, Math.PI * 1.5, true);
ctx.arc(295, 245, 25, Math.PI * 1.5, Math.PI, true);
ctx.arc(310, 245, 40, Math.PI, Math.PI * 0.5, true);
ctx.arc(310, 220, 65, Math.PI * 0.5, 0, true);
ctx.arc(270, 220, 105, 0, Math.PI * 1.5, true);
ctx.arc(270, 285, 170, Math.PI * 1.5, Math.PI, true);
ctx.strokeStyle = '#fff'
ctx.stroke();
上面的代码是利用Canvas 直接画螺旋线的代码。
可以作为下面利用斐波那契数列 画螺旋线的代码的参考
let canvas = document.getElementsByTagName('canvas')[0]
canvas.width = 600
canvas.height = 480
let coor = {
x: 300,
y: 240,
}
//先取背景图中的中间点作为一开始的圆点
let ctx = canvas.getContext('2d')
//获取该canvas的2D绘图环境对象
/*
绘制曲线方法
@param prevR 这是斐波那契数列中前一位的数值,也就是上一截曲线的半径
@param n 这是斐波那契数列中的下标
@param r 这是斐波那契数列当前下标的值,也就是将画曲线的半径
*/
function draw(prevR, n, r) {
let radius = r * 5
//五倍半径画,不然太小了
let startAngle = Math.PI
let endAngle = Math.PI * 0.5
//每个半径只画1/4个圆,所以开始角度和结束角度刚好相差 1/4 * PI
let anticlockwise = true
//设置为逆时针方向画
//改变圆点坐标、开始角度和结束角度
//第三个元素的圆点坐标、开始角度和结束角度上面已经给出,所以从第四个元素开始改变圆点坐标、开始角度和结束角度,也就是从n > 2开始
if (n > 2) {
//下面坐标的改变可以参考上面的图和直接用canvas画的代码。
switch(n % 4) {
case 0:
coor.x = coor.x + (5 * prevR) - radius
startAngle = 0
endAngle = Math.PI * 1.5
break;
case 1:
coor.y = coor.y - (5 * prevR) + radius
startAngle = Math.PI * 1.5
endAngle = Math.PI
break;
case 2:
coor.x = coor.x - (5 * prevR) + radius
startAngle = Math.PI
endAngle = Math.PI * 0.5
break;
case 3:
coor.y = coor.y + (5 * prevR) - radius
startAngle = Math.PI * 0.5
endAngle = 0
break;
}
}
ctx.beginPath()
ctx.arc(coor.x, coor.y, radius, startAngle, endAngle, anticlockwise)
ctx.lineWidth = 1
ctx.strokeStyle = '#fff'
ctx.stroke()
}
//获取斐波那契数列
function getFibonacci(n) {
let arr = []
let i = 0
while (i < n) {
if (i <= 1) {
arr.push(i)
}else {
arr.push(arr[i - 1] + arr[i - 2])
}
i++
}
return arr
}
let fibonacci = getFibonacci(10)
for (let i = 0; i < fibonacci.length; i++) {
//从第三个元素开始画,符合斐波那契数列的规律
if (i >= 2) {
draw(fibonacci[i - 1], i, fibonacci[i])
}
}
—–我是分隔线—–
最终画出来的效果可以看下面这个链接:
Fibonacci spiral