JavaScript分形树

参考博客:c++分形树绘制
js 利用canvas绘制直线、曲线

1、算法描述

假设A点坐标为(x,y),B点坐标为(x0,y0),C点坐标为(x1,y1),D点坐标为(x2,y2),α为主干和枝干的夹角(父枝干和子枝干的夹角),angle为当前要描绘的树干与x轴正方形的夹角(注意angle与α的关系),L为主干的长度。

初始状态下,angle=π/2

实现的算法步骤:
1、画出主干AB,即线段(x,y)-(x0,y0)。

2、计算出D点的坐标,由于屏幕坐标系x正方向为水平向右,y正方向为水平向下,因此
x2 = x0 + 2/3L * cos(angle-α) y2 = y0 - 2/3L * sin(angle-α) (注意是减号)。

3、计算出C点的坐标, x1 = x0 - 2/3L * cos(angle+α) y1 = y0 - 2/3L * sin(angle+α)

4、将D点替换B点,B点替换A点,重复步骤1,画出枝干BD(也即新的“AB”)

5、将C点替换B点,B点替换A点,重复步骤1,画出枝干BC(也即新的“AB”)

6、重新计算枝干长度(应为L乘以一个小于1的系数),这里举例2/3,
则将L设为2/3L,angle分别设为angle+α和angle-α,重复步骤2-6,画出以BC和BD为父枝干的子枝干,直至递归终止条件满足(L小于某个值)

这里写图片描述

2、代码部分

//html
<html>
<head>
<meta charset="utf-8">
<title>分形树</title>
</head>
<body onload='init()'>
  <canvas id="canvas" style="background-color: black;">
</body>
</html>

//js
var canvas, context;
//主干与枝干的夹角
var arg = Math.PI / 15;

function drawTree(px, py, ang, scale, len) {
  //引入偏移随机角度,改变一下形状
   var rn = Math.random()*10 * (Math.PI / 180);

   var x = Math.floor(scale*len*Math.cos(ang));
   var y = Math.floor(scale*len*Math.sin(ang));

   //设置线条颜色
   context.strokeStyle = 'white';
   // 设置线条的宽度
   context.lineWidth = 1;
   // 绘制直线
   context.beginPath();
   // 起点
   context.moveTo(px, py);
   // 终点
   context.lineTo(px+x, py-y);
   context.closePath();
   context.stroke();

   //终止递归
   if (scale*len<20)
          return;

   //递归画出左右分枝
    drawTree(px + x, py - y, ang - arg + rn, scale, scale*len);
    drawTree(px + x, py - y, ang + arg + rn, scale, scale*len);

}

function init() {
   canvas = document.getElementById('canvas');
   canvas.width = 1000;
   canvas.height = 400;

   // 拿到上下文
   context = canvas.getContext('2d');
   // 画分形树
   drawTree(300,300,Math.PI/2,0.82,75);
}

3、运行效果截图

这里写图片描述

猜你喜欢

转载自blog.csdn.net/unirrrrr/article/details/80617410