JavaScript圖形實例:隨機SierPinski三角形

      在JavaScript圖形實例:SierPinski三角形中,咱們介紹了SierPinski三角形的基本繪製方法,在JavaScript圖形實例:迭代函數系統生成圖形一文中,介紹了採用IFS方法生成SierPinski三角形的方法。下面再介紹兩種SierPinski三角形的構造方法,以擴展知識面。javascript

1.隨機點法

      採用隨機點的方法能夠獲得SierPinski三角形。具體過程爲:html

      (1)任意取平面上三點A、B、C,組成一個三角形,並任意取三角形ABC內的一點P;java

      (2)求出P和A、B、C三個頂點中任意一個頂點的中點P1;編程

      (3)描出該中點P1;canvas

      (4)將P1做爲新的P點,轉步驟(2),直到描出的點數達到規定要求(如10000個點)。瀏覽器

      按上述思想,編寫以下的HTML文件。在編程時,爲簡單計,不保證初始的P點必定在三角形ABC內(有可能在三角形外會描出幾個散點,但不影響最後結果),也沒有判斷A、B、C三點可能共線的狀況(此時沒法構成三角形)。有興趣的讀者能夠自行處理這兩種狀況,以完善代碼。dom

<!DOCTYPE html>函數

<head>spa

<title>隨機SierPinski三角形</title>htm

</head>

<body>

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

</canvas>

<script type="text/javascript">

     var canvas=document.getElementById('myCanvas');

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

     function draw()

     {

         ctx.fillStyle="#EEEEFF";

         ctx.fillRect(0,0,300,300);

         ctx.fillStyle="red";

         ctx.font="32px";

         var ax=Math.floor(Math.random()*200+50);

         var ay=Math.floor(Math.random()*200+50);

         var bx=Math.floor(Math.random()*200+50);

         var by=Math.floor(Math.random()*200+50);

         var cx=Math.floor(Math.random()*200+50);

         var cy=Math.floor(Math.random()*200+50);

         var px=Math.floor(Math.random()*200+50);

         var py=Math.floor(Math.random()*200+50);

         var dx=0;

         var dy=0;

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

         {

             index =Math.floor(Math.random()*3+1);

             if (index==1)

             {

                dx = (ax + px)/2;

                dy = (ay + py)/2;

             }

             else if (index == 2)

            {

                dx = (bx + px)/2;

                dy = (by + py)/2;

            }

            else

            {

               dx = (cx + px)/2;

               dy = (cy + py)/2;

            }

            ctx.fillText('.',dx,dy);

            px = dx;

            py = dy;

         }

     }

     draw();

</script>

</body>

</html>

      在瀏覽器中打開包含這段HTML代碼的html文件,能夠看到在瀏覽器窗口中繪製出一個SierPinski三角形,如圖1所示。

 

圖1  SierPinski三角形

      將程序中的調用語句「draw()」改寫爲「window.setInterval('draw()', 1500);」,則在瀏覽器窗口中會每隔1.5秒繪製一個隨機SierPinski三角形,如圖2所示。

 

圖2  每隔1.5秒繪製一個隨機SierPinski三角形

      由圖2能夠看出,有些三角形過小,甚至有些成一條直線,所以,能夠改寫上面的程序,要求隨機取點A、B、C時,保證三個邊長均大於100,且三點不共線。改寫的HTML文件內容以下。

<!DOCTYPE html>

<head>

<title>隨機SierPinski三角形</title>

</head>

<body>

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

</canvas>

<script type="text/javascript">

     var canvas=document.getElementById('myCanvas');

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

     function draw()

     {

         ctx.fillStyle="#EEEEFF";

         ctx.fillRect(0,0,300,300);

         ctx.fillStyle="red";

         ctx.font="32px";

         while (1)

         {

            var ax=Math.floor(Math.random()*200+50);

            var ay=Math.floor(Math.random()*200+50);

            var bx=Math.floor(Math.random()*200+50);

            var by=Math.floor(Math.random()*200+50);

            var cx=Math.floor(Math.random()*200+50);

            var cy=Math.floor(Math.random()*200+50);

            ab=Math.sqrt((bx-ax)*(bx-ax)+(by-ay)*(by-ay));

            ac=Math.sqrt((cx-ax)*(cx-ax)+(cy-ay)*(cy-ay));

            bc=Math.sqrt((cx-bx)*(cx-bx)+(cy-by)*(cy-by));

            if (ab<100 || ac<100 || bc<100) continue;

            if (ab+bc==ac || ab+ac==bc || ac+bc==ab) continue;

            var px=Math.floor(Math.random()*200+50);

            var py=Math.floor(Math.random()*200+50);

            break;

         }

         var dx=0;

         var dy=0;

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

         {

             index =Math.floor(Math.random()*3+1);

             if (index==1)

             {

                dx = (ax + px)/2;

                dy = (ay + py)/2;

             }

             else if (index == 2)

            {

                dx = (bx + px)/2;

                dy = (by + py)/2;

            }

            else

            {

               dx = (cx + px)/2;

               dy = (cy + py)/2;

            }

            ctx.fillText('.',dx,dy);

            px = dx;

            py = dy;

         }

     }

     window.setInterval('draw()', 1500);

</script>

</body>

</html>

      在瀏覽器中打開包含這段改寫後的HTML代碼的html文件,在瀏覽器窗口中也會每隔1.5秒繪製一個隨機SierPinski三角形,如圖3所示,此時每一個隨機SierPinski三角形的最小邊長均會超過100,三角形不會顯得較小。

 

圖3  每隔1.5秒繪製一個較大的隨機SierPinski三角形

      上面程序中隨機點法構造SierPinski三角形是描點10000個獲得的。爲展現描點過程,編寫以下的HTML文件。

<!DOCTYPE html>

<head>

<title>隨機SierPinski三角形</title>

</head>

<body>

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

</canvas>

<script type="text/javascript">

     var canvas=document.getElementById('myCanvas');

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

     ctx.fillStyle="#EEEEFF";

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

     ctx.fillStyle="red";

     ctx.font="32px";

     while (1)

     {

        var ax=Math.floor(Math.random()*400);

        var ay=Math.floor(Math.random()*400);

        var bx=Math.floor(Math.random()*400);

        var by=Math.floor(Math.random()*400);

        var cx=Math.floor(Math.random()*400);

        var cy=Math.floor(Math.random()*400);

        ab=Math.sqrt((bx-ax)*(bx-ax)+(by-ay)*(by-ay));

        ac=Math.sqrt((cx-ax)*(cx-ax)+(cy-ay)*(cy-ay));

        bc=Math.sqrt((cx-bx)*(cx-bx)+(cy-by)*(cy-by));

        if (ab<200 || ac<200 || bc<200) continue;

        if (ab+bc==ac || ab+ac==bc || ac+bc==ab) continue;

        var px=Math.floor(Math.random()*400);

        var py=Math.floor(Math.random()*400);

        break;

     }

     var i=0;

     function draw()

     {

          index =Math.floor(Math.random()*3+1);

          if (index==1)

          {

              dx = (ax + px)/2;

              dy = (ay + py)/2;

           }

           else if (index == 2)

           {

              dx = (bx + px)/2;

              dy = (by + py)/2;

            }

            else

            {

               dx = (cx + px)/2;

               dy = (cy + py)/2;

            }

            ctx.fillText('.',dx,dy);

            px = dx;

            py = dy;

            i++;

            if (i>=10000)

            {

               ctx.fillStyle="#EEEEFF";

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

               ctx.fillStyle="red";

               i=0;

            }

     }

     window.setInterval('draw()',1);

</script>

</body>

</html>

      在瀏覽器中打開包含這段HTML代碼的html文件,在瀏覽器窗口中呈現出一個隨機SierPinski三角形的噴出過程,如圖4所示。

 

圖4  隨機SierPinski三角形的噴出過程

2.按組合數的奇偶性直接描點構造SierPinski三角形

      設有以下的楊輝三角形,若將楊輝三角形的奇數處畫圓點,偶數處留空,則會獲得SierPinski三角形。

 

      因爲楊輝三角中第i行第j列的數字正是組合數C(i,j)的結果。所以,對楊輝三角形中各行各列數字的討論轉化爲對組合數C(n,m)的討論。

      組合數的奇偶性斷定方法爲:

      對於C(n,m),若n&m == m  則C(n,m)爲奇數,不然爲偶數。

      根據這個結論,直接編寫以下的HTML文件。

<!DOCTYPE html>

<head>

<title>按組合數奇偶性構造SierPinski三角形</title>

<script type="text/javascript">

  function draw(id)

  {

     var canvas=document.getElementById(id);

     if (canvas==null)

        return false;

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

     ctx.fillStyle="#EEEEFF";

     ctx.fillRect(0,0,300,300);

     ctx.fillStyle="red";

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

     {

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

            if ((i&j)==j)

                ctx.fillText('.',j+30,i+30);

     }

   }

</script>

</head>

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

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

</canvas>

</body>

</html>

      在瀏覽器中打開包含這段HTML代碼的html文件,能夠看到在瀏覽器窗口中繪製出如圖5所示的SierPinski三角形。

 

圖5  SierPinski三角形 

相關文章
相關標籤/搜索