zoukankan      html  css  js  c++  java
  • 分形谢尔宾斯基三角形

        大学时候,有上过关于图像学相关的课程,当时图像学课程的老师,听说在学院里都非常的出名,在入学之前就有听说,当初信誓旦旦的,想好好学习,可以还是挡不过大学里的自由的生活的诱惑,还是没能坚持下来。

        当初对图形学相关的印象也是停留在绚丽的图形图像上,对于实现感觉就是高深莫测的东西(刁吊的MFC),现在工作也快一年多了,可能是东西做的多了,对做任何东西都有一股自信,所以想把当初的东西捡起来。

    原理:(摘自百度百科)

    1.取一个实心的三角形。(多数使用等边三角形)

    2.沿三边中点的连线,将它分成四个小三角形。

    3.去掉中间的那一个小三角形。

    4.对其余三个小三角形重复1。

    取一个正方形或其他形状开始,用类似的方法构作,形状也会和谢尔宾斯基三角形相近。

    image

     

    先贴上js实现效果:

    迭代效果

    image        image  image     image

    关键代码:

    页面:

    使用HTML5中的canvas画布进行图像的绘制,并提供一个可供输入的文本框记录迭代次数。

    <body style='margin:0 auto;800px;'>
        <div>
            <input type='text' id='Count'/><input type='button' value='运行' id='btn' />
        </div>
        <canvas id='cav' width='500' height='500' style='border:1px solid black;'></canvas>
    </body>

    js实现思路:

    定义最大的等边三角形,每迭代一次,取三角各边的中点,然后将中间点进行连接,对于中间的三角形不进行二次迭代,使用此取巧的方式代替“挖空”中间三角形的概念,逻辑很简单。

    js:

    1、点对象

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

    2、画线

    function drawLine (ctx,point1,point2,point3) {
                ctx.beginPath();
                ctx.moveTo(point1.x, point1.y);
                ctx.lineTo(point2.x, point2.y);
                ctx.lineTo(point3.x, point3.y);
                ctx.closePath();
                ctx.stroke();
            }

    3、取中间点

    function getMiddlePoint (pointA,pointB) {
                var x = (pointA.x + pointB.x)/2;
                var y = (pointA.y + pointB.y)/2;
                return new point(x,y);
            }

    4、迭代函数

    function drawOri (ctx,pointA,pointB,pointC,count) {
                if (count>2) {
                    drawLine(ctx,pointA,pointB,pointC);
                    var t_A = getMiddlePoint(pointA,pointB);
                    var t_B = getMiddlePoint(pointA,pointC);
                    var t_C = getMiddlePoint(pointB,pointC);
                    count -= 1;
                    drawOri(ctx,t_A,pointB,t_C,count);
                    drawOri(ctx,t_A,t_B,pointA,count);
                    drawOri(ctx,pointC,t_B,t_C,count);
                } else if(count==2){
                    drawLine(ctx,pointA,pointB,pointC);
                    var t_A = getMiddlePoint(pointA,pointB);
                    var t_B = getMiddlePoint(pointA,pointC);
                    var t_C = getMiddlePoint(pointB,pointC);
                    count -= 1;
                    drawOri(ctx,t_A,t_B,t_C,count);
                }else{
                    drawLine(ctx,pointA,pointB,pointC);
                }
            }

    完整可运行代码如下:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset='utf-8'></meta>
        <title>谢尔宾斯基三角形</title>
        <style type="text/css"></style>
        <script type="text/javascript">
        
            function point (x,y) {
                this.x = x;
                this.y = y;
            }
    
            function drawLine (ctx,point1,point2,point3) {
                ctx.beginPath();
                ctx.moveTo(point1.x, point1.y);
                ctx.lineTo(point2.x, point2.y);
                ctx.lineTo(point3.x, point3.y);
                ctx.closePath();
                ctx.stroke();
            }
    
            function getMiddlePoint (pointA,pointB) {
                var x = (pointA.x + pointB.x)/2;
                var y = (pointA.y + pointB.y)/2;
                return new point(x,y);
            }
    
            function drawOri (ctx,pointA,pointB,pointC,count) {
                if (count>2) {
                    drawLine(ctx,pointA,pointB,pointC);
                    var t_A = getMiddlePoint(pointA,pointB);
                    var t_B = getMiddlePoint(pointA,pointC);
                    var t_C = getMiddlePoint(pointB,pointC);
                    count -= 1;
                    drawOri(ctx,t_A,pointB,t_C,count);
                    drawOri(ctx,t_A,t_B,pointA,count);
                    drawOri(ctx,pointC,t_B,t_C,count);
                } else if(count==2){
                    drawLine(ctx,pointA,pointB,pointC);
                    var t_A = getMiddlePoint(pointA,pointB);
                    var t_B = getMiddlePoint(pointA,pointC);
                    var t_C = getMiddlePoint(pointB,pointC);
                    count -= 1;
                    drawOri(ctx,t_A,t_B,t_C,count);
                }else{
                    drawLine(ctx,pointA,pointB,pointC);
                }
            }
    
            window.onload=function () {
                var cav = document.getElementById('cav');
                var ctx = cav.getContext('2d');
                ctx.strokeStyle="#3333ff";
                drawOri(ctx,new point(230,10),new point(10,450),new point(480,450),7);
                var btn = document.getElementById('btn');
                var val = 0;
                btn.onclick=function () {
                    val = document.getElementById('Count').value;
                    if (parseInt(val).toString()!='NaN') {
                        ctx.clearRect(0,0,500,500);
                        drawOri(ctx,new point(230,10),new point(10,450),new point(480,450),val);
                    } else{
                        alert('error number');
                    };
                }
            }
        </script>
    </head>
    <body style='margin:0 auto;800px;'>
        <div>
            <input type='text' id='Count'/><input type='button' value='运行' id='btn' />
        </div>
        <canvas id='cav' width='500' height='500' style='border:1px solid black;'></canvas>
    </body>
    </html>

    编后语:

       可能实现方式上算法不是最好的,大家如果有更好的js实现技巧,欢迎交流指导!

    我们要走的路,有着太多的不确定,他人的一句劝诫,自己的一个闪念,偶尔的得与失,都时刻在改变着我们命运的走向。世事难以预料,遇事无须太执,谁都无法带走什么,又何必纠结于某一人、某一时、某一事。只有看开了,想通了,才能随缘、随性、随心而为,不急不躁,不悲不欢,不咸不淡。
  • 相关阅读:
    按列数自动换行
    百度C 语言吧 · 问题资料大全
    最新动态.某美女象山旅游计划
    被点名了,玩个游戏。
    我们仍未知道那天所看见的题的解法 1
    我们仍未知道那天所看见的题的解法 2
    算法初探 平衡树
    排列组合
    HttpRunner2.X开源接口测试框架学习(一):介绍与安装
    jmeter基础一:JMeter的主要测试组件总结
  • 原文地址:https://www.cnblogs.com/szfBlogs/p/4896334.html
Copyright © 2011-2022 走看看