zoukankan      html  css  js  c++  java
  • JavaScript图形实例:模仿海龟作图

          海龟作图最初源自20世纪60年代的Logo编程语言。在海龟作图中,我们可以编写指令让一个虚拟的海龟在屏幕上来回移动。这个海龟带着一只钢笔,我们可以让海龟无论移动到哪都使用这只钢笔来绘制线条。通过编写代码,以各种很酷的模式移动海龟,我们可以绘制出令人惊奇的图片。

          例如,让海龟从某个点开始,向前走100(画出第一条直线),右转90°后,再向前走100(画出第2条直线,它与第1条直线垂直),之后再右转90°,向前走100(画出第3条直线,它与第1条直线平行,与第2条直线垂直),最后右转90°,向前走100(画出第4条直线)。这4条直线正好构成一个边长为100的正方形。

          使用海龟作图,我们不仅能够只用几行代码就创建出令人印象深刻的图形效果,而且还可以跟随海龟看看每行代码如何影响到它的移动。这能够帮助我们理解代码的逻辑。所以海龟作图常被用作初学者学习程序设计的一种方式。例如,少儿学习编程就常将海龟作图作为启蒙。

    1. 正N边形

    从坐标原点开始(moveTo(0,0)),进行N次循环操作,循环中执行如下操作:

        向Y轴正方形前进len,lineTo(0,len);

        坐标原点移到(0,len)处;

        旋转(360/n)°;

    循环执行完后,用stroke()方法绘制出N边形。

    编写如下的HTML文件。

    <!DOCTYPE html>

    <head>

    <title>正N边形</title>

    <script type="text/javascript">

      function draw(id)

      {

         var canvas=document.getElementById(id);

         if (canvas==null)

            return false;

         var context=canvas.getContext('2d');

         context.fillStyle="#EEEEFF";

         context.fillRect(0,0,400,400);

         context.translate(100, 100);

         context.strokeStyle ='red';

         context.lineWidth = 2;

         var n=5;

         var angle=360/n;

         context.beginPath();

         context.moveTo(0, 0);

         for (i =1; i <=n; i++)

         {

            context.lineTo(0, 400/n);

            context.translate(0, 400/n);

            context.rotate(-angle* (2 * Math.PI / 360));

          }

          context.stroke();

       }

    </script>

    </head>

    <body onload="draw('myCanvas');">

    <canvas id="myCanvas" width="400" height="400" style="border:3px double #996633;">

    </canvas>

    </body>

    </html>

    在浏览器中打开包含这段HTML代码的html文件,可以看到在画布中绘制出如图1所示的正五边形图案。

                   

    图1  正五边形   

          上面程序中每次旋转角度为360/n,因此绘制的图形为正N边形。若旋转角度多加5°,即修改语句“var angle=360/n;” 为“var angle=360/n+5;”,则在画布中绘制出如图2所示的图形,这个图形的起点与终点明显不是同一个点。若再多绘制几条线,将循环语句“for (i =1; i <=n; i++)”改为“for (i =1; i <=20; i++)”,则在画布中绘制出如图3所示的图形。

     

    图2  旋转角度多加5°的图形 

     

    图3  旋转角度多加5°,边数为20的图形

          将上面程序段中加黑的11行代码替换为如下的语句,其余部分不变,则在画布中绘制出如图4所示的图形。

         var n=3;

         var angle=360/n+5;

         context.beginPath();

         context.moveTo(0, 0);

         for (i =1; i <=72; i++)

         {

            context.lineTo(0, 200);

            context.translate(0, 200);

            context.rotate(-angle* (2 * Math.PI / 360));

          }

          context.stroke();

     

    图4  通过旋转125°绘制72条边得到的图案

        后面我们给出代码时,如未给出完整的HTML文件内容,只给出核心的绘制程序,就意味着只需替换绘制图1的HTML文件中带有段落底纹的语句,其余部分保持不变。

        如果每次绘制的线段长度递增,会如何呢?修改核心代码如下,则在画布中绘制出如图5所示的正方形螺旋线。

         var n=4;

         var angle=360/n;

         context.beginPath();

         context.moveTo(0, 0);

         for (i =100; i <=200; i+=4)

         {

            context.lineTo(0, i);

            context.translate(0, i);

            context.rotate(-angle* (2 * Math.PI / 360));

          }

          context.stroke();

      

    图5 正方形螺旋线

          如果每次绘制的线段长度递增,且旋转角度为100°,又会如何呢?修改核心代码如下,则在画布中绘制出如图6所示的图形。

         var n=4;

         var angle=360/n+10;

         context.beginPath();

         context.moveTo(0, 0);

         for (i =100; i <=200; i++)

         {

            context.lineTo(0, i);

            context.translate(0, i);

            context.rotate(-angle* (2 * Math.PI / 360));

          }

          context.stroke();

      

    图6  N为4,旋转角度为100°且边长递增的图形

          若采用多种颜色,例如红橙黄绿颜4种色轮流绘制线段。修改核心代码如下,则在画布中绘制出如图7所示的图形。

         var colors = ['red','orange','yellow', 'green', 'cyan','blue', 'purple' ];

         var n=4;

         var angle=360/n+10;

         for (i =100; i <=200; i++)

         {

            context.strokeStyle = colors[i % 4];

            context.beginPath();

            context.moveTo(0, 0);

            context.lineTo(0, i);

            context.translate(0, i);

            context.rotate(-angle* (2 * Math.PI / 360));

            context.stroke();

          }

      

    图7 采用四种颜色绘制的图案

        修改核心代码如下,则在画布中绘制出如图8所示的图形。

         var n=6;

         var angle=360/n+1;

         for (i =0; i <180; i++)

         {

            context.beginPath();

            context.moveTo(0, 0);

            context.lineTo(0,i/3);

            context.translate(0, i/3);

            context.rotate(-angle* (2 * Math.PI / 360));

            context.stroke();

            context.rotate(Math.PI /2);

          }

      

    图8  线球

    2.五角星

         我们通过控制“海龟”的旋转角度,可以绘制出不同的图形,例如五角星等图形。修改核心代码如下。

         context.beginPath();

         context.moveTo(0, 0);

         for (i =1; i <=5; i++)

         {

            context.lineTo(150,0);

            context.translate(150, 0);

            context.rotate(144* (2 * Math.PI / 360));

          }

          context.stroke();

          在浏览器中打开修改后的html文件,可以在画布中绘制出如图9所示的五角星。

      

    图9  五角星图案

          修改核心代码如下,则在画布中绘制出如图10所示的图形。

         context.beginPath();

         context.moveTo(0, 0);

         for (i =1; i <=36; i++)

         {

            context.lineTo(0,180);

            context.translate(0, 180);

            context.rotate(175* (2 * Math.PI / 360));

          }

          context.stroke();

      

    图10 每次旋转175°绘制的图形

          先修改坐标原点的位置为“context.translate(200, 50);”,以使绘制的图形不超出画布范围。再修改核心代码如下,则在画布中绘制出如图11所示的图形。

         context.beginPath();

         context.moveTo(0, 0);

         for (i =1; i <=18; i++)

         {

            context.lineTo(0,150);

            context.translate(0, 150);

            if (i%2==0)

               context.rotate(175* (2 * Math.PI / 360));

            else

               context.rotate(225* (2 * Math.PI / 360));

          }

          context.stroke();

      

    图11 放射状尖刺图案

    3.多角星

          我们用图1的程序可以绘制正N边形,若用正N边形的每个边长作为一个等边三角形的一边向外绘制一个等边三角形,这N个等边三角形形成了N个突出的角,可绘制出一个多角星图案。

    编写的HTML文件内容如下。

    <!DOCTYPE html>

    <head>

    <title>多角星</title>

    <script type="text/javascript">

      function draw(id)

      {

         var canvas=document.getElementById(id);

         if (canvas==null)

            return false;

         var context=canvas.getContext('2d');

         context.fillStyle="#EEEEFF";

         context.fillRect(0,0,400,400);

         context.translate(300, 200);

         context.strokeStyle ='red';

         context.lineWidth = 2;

         var colors = ['red','orange','yellow', 'green', 'cyan','blue', 'purple' ];

         var L=50;  // 边长

         var n=12;  // 角的个数

         var angle=180-360/n;

         context.moveTo(0, 0);

         for (i =1; i <=n; i++)

         {

            context.rotate(angle* (2 * Math.PI / 360));    

            context.translate(0, L);

            context.beginPath();

            context.moveTo(0, 0);

            context.rotate(180* (2 * Math.PI / 360)); 

            for (k=1;k<=3;k++)    // 绘制等边三角形

            {

                context.lineTo(0, L);

                context.translate(0, L);

                context.rotate(-120* (2 * Math.PI / 360));

            }

            context.closePath();

            context.stroke();

            context.fillStyle=colors[i%7];

            context.fill();

          }

       }

    </script>

    </head>

    <body onload="draw('myCanvas');">

    <canvas id="myCanvas" width="400" height="400" style="border:3px double #996633;">

    </canvas>

    </body>

    </html>

    在浏览器中打开包含这段HTML代码的html文件,可以看到在画布中绘制出如图12所示的多角星图案1。

      

    图12 多角星图案1 

          上面程序中语句“context.rotate(-120* (2 * Math.PI / 360));”修改为“context.rotate(120* (2 * Math.PI / 360));”,则在画布中绘制出如图13所示的多角星图案2。

      

    图13  多角星图案2 

  • 相关阅读:
    Shader实例:溶解效果(Dissolve)
    Shader实例:扭曲,漩涡
    Shader实例:边缘发光和描边
    Shader实例:2D流光
    基础知识:Q&A
    Shader实例:一台旧电视
    Unity Lightmap动态加载研究
    Excel转Json,Json转CSharp
    瓦特平台全部出售69.9元、为了学习、为了进步、为了明天!
    分享一个文件查找、替换制定的字符或数字之CS程序、附带源码
  • 原文地址:https://www.cnblogs.com/cs-whut/p/13191040.html
Copyright © 2011-2022 走看看