• 分形谢尔宾斯基地毯


         谢尔宾斯基地毯的构造与谢尔宾斯基三角形相似,区别仅在于谢尔宾斯基地毯是以正方形而非等边三角形为基础的。将一个实心正方形划分为的9个小正方形,去掉中间的小正方形,再对余下的小正方形重复这一操作便能得到谢尔宾斯基地毯。

        js实现思路和我之前写的分形--谢尔宾斯基三角形的类似。

    js效果:

    imageimage

    贴关键代码:

    1、画点

    function point(x,y){
            this.x = x;
            this.y = y;
        }

    2、画线

    function drawLine (ctx,point1,point2) {
            ctx.beginPath();
            ctx.moveTo(point1.x,point1.y);
            ctx.lineTo(point2.x,point2.y);
            ctx.closePath();
            ctx.stroke();
        }
    3、画矩形
    function drawRect (ctx,point1,point2,point3,point4) {
            ctx.beginPath();
            ctx.moveTo(point1.x,point1.y);
            ctx.lineTo(point2.x,point2.y);
            ctx.lineTo(point3.x,point3.y);
            ctx.lineTo(point4.x,point4.y);
            ctx.closePath();
            ctx.stroke();
        }

    4、取矩形各边的3等分点的两个中间点坐标

    ///获取3等分的两个中间点坐标
        function getTwoMiddlePoint (point1,point2) {
            var temp1 = new point(0,0);
            var temp2 = new point(0,0);
            if (point1.x == point2.x) {
                var indentX = Math.abs(point1.y - point2.y)/3;
                if (point1.y>point2.y) {
                    temp1.x = point2.x;
                    temp1.y = point2.y + indentX;
                    temp2.x = point1.x;
                    temp2.y = point2.y + indentX*2;
                } else{
                    temp1.x = point1.x;
                    temp1.y = point1.y + indentX*2;
                    temp2.x = point2.x;
                    temp2.y = point1.y + indentX;
                }
            } else if (point1.y == point2.y) {
                var indentY = Math.abs(point1.x - point2.x)/3;
                if (point1.x>point2.x) {
                    temp1.x = point2.x + indentY;
                    temp1.y = point2.y;
                    temp2.x = point2.x + indentY*2;
                    temp2.y = point1.y;
                } else{
                    temp1.x = point1.x + indentY*2;
                    temp1.y = point1.y;
                    temp2.x = point1.x + indentY;
                    temp2.y = point2.y;
                }
            }
            return new doublePoint(temp1,temp2);
        }

    5、迭代函数

    function drawMengo(ctx,pointa,pointb,pointc,pointd,count) {
            if (count>=2) {
                drawRect(ctx,pointa,pointb,pointc,pointd);
                var double_ab = getTwoMiddlePoint(pointa,pointb);
                console.log(double_ab);
                var double_bc = getTwoMiddlePoint(pointb,pointc);
                var double_cd = getTwoMiddlePoint(pointd,pointc);
                console.log(double_cd);
                var double_da = getTwoMiddlePoint(pointa,pointd);
                {
                    drawLine(ctx,double_ab.point1,double_cd.point1);
                    drawLine(ctx,double_ab.point2,double_cd.point2);
                    drawLine(ctx,double_da.point1,double_bc.point1);
                    drawLine(ctx,double_da.point2,double_bc.point2);
                    count -= 1;
                    drawMengo(ctx,pointa,double_ab.point2,new point(double_ab.point2.x, double_da.point2.y),double_da.point2,count);
                    drawMengo(ctx,double_ab.point2,double_ab.point1,new point(double_ab.point1.x, double_da.point2.y),
                        new point(double_ab.point2.x, double_da.point2.y),count);
                    drawMengo(ctx,double_ab.point1,pointb,double_bc.point2,new point(double_ab.point1.x, double_bc.point2.y),count);
    
                    drawMengo(ctx,double_da.point2,new point(double_ab.point2.x, double_da.point2.y),
                        new point(double_ab.point2.x, double_da.point1.y),double_da.point1,count);
                    drawMengo(ctx,new point(double_ab.point1.x, double_bc.point2.y),double_bc.point2,double_bc.point1,
                        new point(double_ab.point1.x,double_bc.point1.y),count);
    
                    drawMengo(ctx,double_da.point1,new point(double_ab.point2.x,double_da.point1.y),double_cd.point2,pointd,count);
                    drawMengo(ctx,new point(double_ab.point2.x,double_da.point1.y),new point(double_ab.point1.x,double_da.point1.y),double_cd.point1,double_cd.point2,count);
                    drawMengo(ctx,new point(double_ab.point1.x,double_da.point1.y),double_bc.point1,pointc,double_cd.point1,count);
                }
            } else{
                drawRect(ctx,pointa,pointb,pointc,pointd);
            }
        }

    完整可运行代码:

    <html>
    <head>
        <title>门格海绵--谢尔宾斯基地毯</title>
        <meta charset='utf-8'/>
        <script type="text/javascript">
        function point(x,y){
            this.x = x;
            this.y = y;
        }
    
        function doublePoint (point1,point2) {
            this.point1 = point1;
            this.point2 = point2;
        }
    
        function drawLine (ctx,point1,point2) {
            ctx.beginPath();
            ctx.moveTo(point1.x,point1.y);
            ctx.lineTo(point2.x,point2.y);
            ctx.closePath();
            ctx.stroke();
        }
    
        function drawRect (ctx,point1,point2,point3,point4) {
            ctx.beginPath();
            ctx.moveTo(point1.x,point1.y);
            ctx.lineTo(point2.x,point2.y);
            ctx.lineTo(point3.x,point3.y);
            ctx.lineTo(point4.x,point4.y);
            ctx.closePath();
            ctx.stroke();
        }
    
        ///获取3等分的两个中间点坐标
        function getTwoMiddlePoint (point1,point2) {
            var temp1 = new point(0,0);
            var temp2 = new point(0,0);
            if (point1.x == point2.x) {
                var indentX = Math.abs(point1.y - point2.y)/3;
                if (point1.y>point2.y) {
                    temp1.x = point2.x;
                    temp1.y = point2.y + indentX;
                    temp2.x = point1.x;
                    temp2.y = point2.y + indentX*2;
                } else{
                    temp1.x = point1.x;
                    temp1.y = point1.y + indentX*2;
                    temp2.x = point2.x;
                    temp2.y = point1.y + indentX;
                }
            } else if (point1.y == point2.y) {
                var indentY = Math.abs(point1.x - point2.x)/3;
                if (point1.x>point2.x) {
                    temp1.x = point2.x + indentY;
                    temp1.y = point2.y;
                    temp2.x = point2.x + indentY*2;
                    temp2.y = point1.y;
                } else{
                    temp1.x = point1.x + indentY*2;
                    temp1.y = point1.y;
                    temp2.x = point1.x + indentY;
                    temp2.y = point2.y;
                }
            }
            return new doublePoint(temp1,temp2);
        }
    
        function drawMengo(ctx,pointa,pointb,pointc,pointd,count) {
            if (count>=2) {
                drawRect(ctx,pointa,pointb,pointc,pointd);
                var double_ab = getTwoMiddlePoint(pointa,pointb);
                console.log(double_ab);
                var double_bc = getTwoMiddlePoint(pointb,pointc);
                var double_cd = getTwoMiddlePoint(pointd,pointc);
                console.log(double_cd);
                var double_da = getTwoMiddlePoint(pointa,pointd);
                {
                    drawLine(ctx,double_ab.point1,double_cd.point1);
                    drawLine(ctx,double_ab.point2,double_cd.point2);
                    drawLine(ctx,double_da.point1,double_bc.point1);
                    drawLine(ctx,double_da.point2,double_bc.point2);
                    count -= 1;
                    drawMengo(ctx,pointa,double_ab.point2,new point(double_ab.point2.x, double_da.point2.y),double_da.point2,count);
                    drawMengo(ctx,double_ab.point2,double_ab.point1,new point(double_ab.point1.x, double_da.point2.y),
                        new point(double_ab.point2.x, double_da.point2.y),count);
                    drawMengo(ctx,double_ab.point1,pointb,double_bc.point2,new point(double_ab.point1.x, double_bc.point2.y),count);
    
                    drawMengo(ctx,double_da.point2,new point(double_ab.point2.x, double_da.point2.y),
                        new point(double_ab.point2.x, double_da.point1.y),double_da.point1,count);
                    drawMengo(ctx,new point(double_ab.point1.x, double_bc.point2.y),double_bc.point2,double_bc.point1,
                        new point(double_ab.point1.x,double_bc.point1.y),count);
    
                    drawMengo(ctx,double_da.point1,new point(double_ab.point2.x,double_da.point1.y),double_cd.point2,pointd,count);
                    drawMengo(ctx,new point(double_ab.point2.x,double_da.point1.y),new point(double_ab.point1.x,double_da.point1.y),double_cd.point1,double_cd.point2,count);
                    drawMengo(ctx,new point(double_ab.point1.x,double_da.point1.y),double_bc.point1,pointc,double_cd.point1,count);
                }
            } else{
                drawRect(ctx,pointa,pointb,pointc,pointd);
            }
        }
        window.onload=function  () {
            var cav = document.getElementById('cav');
            var ctx = cav.getContext('2d');
            ctx.strokeStyle = 'green';//rgba(100,200,100,50);
            var count = document.getElementById('num');
            drawMengo(ctx,new point(10,10),new point(709,10),new point(709,709),new point(10,709),count.value);
    
            var btn = document.getElementById('clk');
            btn.onclick=function  () {
                ctx.clearRect(0,0,800,800);
                drawMengo(ctx,new point(10,10),new point(709,10),new point(709,709),new point(10,709),count.value);
            }
        }
        </script>
    </head>
    <body>
        <div style='margin:0 auto;'>
            <div>
                <input type='text' id='num' value='6'/>
                <input type='button' id='clk' value='run'/>
            </div>
            <canvas id='cav' width='750' height='750' style='border:1px solid red;'></canvas>
        </div>
    </body>
    </html>

    编后语:

         迭代函数的逻辑其实不复杂,主要是靠细心,注意对应点的连接,最后可以得到最终效果,算法很挫,还请指教。

    我们要走的路,有着太多的不确定,他人的一句劝诫,自己的一个闪念,偶尔的得与失,都时刻在改变着我们命运的走向。世事难以预料,遇事无须太执,谁都无法带走什么,又何必纠结于某一人、某一时、某一事。只有看开了,想通了,才能随缘、随性、随心而为,不急不躁,不悲不欢,不咸不淡。
  • 相关阅读:
    华为S12700 NQA配置
    斐讯K1 K2 开启Telnet
    存储的一些基本概念(HBA,LUN)
    华为AR配置内部服务器示例(只有1个公网IP)
    使用nginx 做kbmmw REST 服务的负载均衡
    第一个 macOS 64位 kbmmw 服务器
    使用FMXlinux 开发linux 桌面应用
    推荐一套免费跨平台的delphi 哈希及加密算法库
    使用kbmmw 的调度事件动态显示时间
    提高sqlite 的运行性能(转载)
  • 原文地址:https://www.cnblogs.com/szfBlogs/p/4896493.html
Copyright © 2020-2023  润新知