js实现蕨类植物叶子,叶子分形图形

分形图形很是奇妙,这里展示的是蕨类植物叶子的分形图形。

这里使用Canvas 通过描点的方式来绘制图形,先说一下原理:

先来个方程:

 

或许看完这个觉得很懵逼,这里就不说这个方程怎么计算了。由这个方程可以得到 8个式子,两两一组有四组

第一组函数:

f(x, y) = 0

f(x, y) = 0.16y

第二组函数:

f(x, y) = 0.2x - 0.26y

f(x, y) = 0.23x + 0.22y +1.6

第三组函数:

f(x, y) = -0.15x +0.28y

f(x, y) = 0.26x +0.24y +0.44

第四组函数:

f(x, y) = 0.85x +0.04y

f(x, y) = -0.04x + 0.85y +1.6

得到这四组式子后,我们需要随机抽取一组(抽取概率为,第一组1% ,第二组7% , 第三组7% 第四组百分之85%

先随机两个随机出数x0和y0放进这一组中计算,每一组的第一个式子代入x0和y0进去得到的f(x,y) 也就是得到的结果,作为x1,

第二个式子代入x0和y0得到的结果y1。

拿到x1和y1后在和上面规则一样,在随机出一组式子,和上面一样,把x1和y1分别代入进去随机出来的哪一组式子的第一个式子和第二个式子得出x2和y2,

这个过程重复20次左右会得到x20 和y20,这个x20和y20我们就作为点的坐标给描出来。这样就迭代得到一个点,要20000个点就重复20000次(也差不多这么多点描出来的叶子才好看)。

 

如果你把第一组的得出的x1和y1代入后 ,然后没有随机一组式子,迭代20次就会得到下面的图形

当然照着上面的做法完了后会得到什么,你会看见你屏幕上什么都没有,或许还是有一点点的

这时候我们在最后ctx.fillRect(x, y, 1, 1)的x坐标和y坐标都加500,意思x坐标移动500 y坐标移动500。然后图在中间了,但是还是看不见那么在这样

ctx.fillRect(x*30+500, y*30+500, 1, 1)给*30放大

你会发现TMD倒着的。这时候改改ctx.fillRect(x*30+500, - y*30+500, 1, 1)  在y前面加负号,还可以ctx.fillRect(-x*30+500, - y*30+500, 1, 1)在x前面加负号看看

 

上面标红的地方你可以试试调调数字有些会有特别的图。这里我把第三组式子的概率调到了40.

 

你还可以试着改改上面的那几组式子,或者添加新的式子,上面标红的都可以试着改改,得到一些新的,图形。这里我就没有测试了。

下面是我写了个觉得比较通俗易懂的代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>QAQ</title>
<style>
body {
    padding: 0;
    margin: 0
} 
#mycanvas {
    margin:20px; 
}
</style>
</head>
<body>
    <canvas id="mycanvas" width="2048px" height="1266px" style="background-color:black;"></canvas>
<script>
var mycanvas = document.getElementById("mycanvas");
    mycanvas.width = 2048;
    mycanvas.height = 1266;
    var ctx = mycanvas.getContext('2d');
        ctx.clearRect(0, 0, 2048, 1266);
        ctx.fillStyle = "#0f0";      
//把每个方程用立即执行函数表达式(先不执行)存放到一个数组,在把这四组放到pwowq的数组 pwowq
= { F1: [ (function(x, y) { return 0; }), (function(x, y) { return 0.16 * y; }) ], F2: [ (function(x, y) { return 0.2 * x - 0.26 * y; }), (function(x, y) { return 0.23 * x + 0.22 * y + 1.6; }) ], F3: [ (function(x, y) { return -0.15 * x + 0.28 * y; }), (function(x, y) { return 0.26 * x + 0.24 * y + 0.44; }) ], F4: [ (function(x, y) { return 0.85 * x + 0.04 * y; }), (function(x, y) { return -0.04 * x + 0.85 * y + 1.6; }) ], } // 按1% 7% 7% 85%的比例放到newArr数组 var newArr = [] for(let i = 0; i < 1; i++){ newArr.push(pwowq.F1) } for(let ii = 0;ii<7; ii++){ newArr.push(pwowq.F2) } for(let iii = 0;iii<7;iii++){ newArr.push(pwowq.F3) } for(let iiii = 0; iiii<85; iiii++){ newArr.push(pwowq.F4) } var count = 0; render = function() { var QAQ; var f; var x = Math.random(); var y = Math.random(); // for (var i = 0;i<10000 ;i++) { for(var jj = 0; jj < 20; jj++) {/*这里就是传入两随机数x0,y0, 在随机抽取式子,迭代20次*/ f = newArr[~~(Math.random()*100)];//或者f = parseInt(Math.random()*100) QAQ = [f[0](x, y), f[1](x, y)]; x = QAQ[0]; y = QAQ[1]; } ctx.fillRect(x*30+500, -y*30+500, 1, 1);/*渲染点*/ if(count < 10000){ window.requestAnimationFrame(render)//js的做动画的一种方式 // window.requestAnimationFrame(render)//取消注释以双倍的速度渲染 count++ } // } }; //render() window.requestAnimationFrame(render); </script> </body> </html>

 

posted @ 2018-06-19 00:25  弱音  阅读(1410)  评论(0编辑  收藏  举报