javascript绘制谢尔宾斯基三角形(Sierpinski triangle)

    自从上一次绘制雪花曲线(用javascript绘制雪花(Koch曲线))之后,对简单分形更加喜欢,太复杂的只能欣赏了,简单分形还是决定一个一个的用代码绘制出来,html5中的canvas标签相当方便,本文继续使用javascript + canvas的模式。
 
    谢尔宾斯基三角形由波兰数学家谢尔宾斯基在1915年提出。详情见wiki
 
    总体上说来这个三角形比雪花曲线要来的简单,基本思路和雪花曲线类似,所以没有什么难度。
 
    
    图1
 
    图1为谢尔宾斯基三角形的变化规律,由于都是正三角形,所以几个点处理起来很方便。
 
    
    图2
 
    图2中我们约定了正三角形的三个点分别为P1、P2、P3,中心点的三个点为P4、P5、P6。我们约定:在方法调用的时候P2和P3在一条直线,X3大于X2。这样约定在递归方法中会比较容易处理。
 
    首先是body代码,加入canvas标签。并加入适当样式。
    
<style>
    canvas{border:2px solid #000; background:#fff;}
</style>

<body onload="draw()">
<input type="text" value="1" id="txtDepth"/>
<input type="button" value="绘制" onclick="draw()"/>
<input type="checkbox" id="cbox">彩色
<br />
<canvas id="cantest" width="500px" height="500px"></canvas>
</body>
 
    主要代码:
<script language="javascript">
    function draw(){
        var can = document.getElementById("cantest");
        if(can.getContext){
            can.height = can.height;
            var ctx = can.getContext("2d");
            ctx.strokeStyle = "#000";

            var depth = parseInt(document.getElementById("txtDepth").value); //绘制维度

            Sierpinski(ctx, 250.00, 20.00, 0.00, 500 * Math.sin(Math.PI / 3+ 20500.00,500 * Math.sin(Math.PI / 3+ 20, depth , 0);
        }else{
            alert("不支持Canvas");
        }
    }

    
    function Sierpinski(ctx, x1, y1,
                             x2, y2,
                             x3, y3,
                             depth,  //维度
                             nowDepth){ //当前维度
        nowDepth = nowDepth + 1;

        if(depth == 0){
            return false;
        }

        if(depth == nowDepth){
            ctx.beginPath();
            if(document.getElementById("cbox").checked){
                ctx.fillStyle = getColor();
            }else{
                 ctx.fillStyle = "#000";
            }
            ctx.moveTo(x1, y1);
            ctx.lineTo(x2, y2);
            ctx.lineTo(x3, y3);
            ctx.fill();  //填充块
            return false;
        }

        var x4 = x2 + (x3 - x2) / 2;
        var x5 = x2 + (x3 - x2) / 4;
        var x6 = x2 + (x3 - x2) * 3 / 4;
        var y4 = 0.00;
        var y5 = 0.00;
        var y6 = 0.00;
       
        y4 = y1 + (x3 - x2) * Math.sin(Math.PI / 3);
        y5 = y1 + (x3 - x2) / 2 * Math.sin(Math.PI / 3);
        y6 = y1 + (x3 - x2) / 2 * Math.sin(Math.PI / 3);
       
        Sierpinski(ctx, x1, y1, x5, y5, x6, y6, depth, nowDepth);
        Sierpinski(ctx, x5, y5, x2, y2, x4, y4, depth, nowDepth);
        Sierpinski(ctx, x6, y6, x4, y4, x3, y3, depth, nowDepth);
    }

    function getColor(){
        return '#'+(Math.random()*0xffffff<<0).toString(16);
    }
</script>
 
运行后效果如下:
    
    图3 黑白
 
    
    图4 彩色
 
    这次其实用画线的方法也是可以得,只是上次用过了,下次看到好玩的分形,继续玩一玩,canvas标签功能着实强大,应该好好发掘。
 
    预览地址:http://runjs.cn/detail/scdfmilp
posted @ 2013-01-28 17:36  MNight  阅读(607)  评论(0编辑  收藏  举报