JavaScript圖形實例:利用插值實現圖像漸變

      描述由一個圖形變化爲另外一個圖形過程當中的各個中間圖形,稱爲漸變圖形。能夠利用插值算法求得各個漸變圖形。javascript

      設在源圖形和目標圖形上各取M個對應座標點,並分別保存到數組中,源圖形用數組SX[M]和SY[M]保存M個座標點(sx,sy),目標圖形用數組DX[M]和DY[M]保存M個座標點(dx,dy)。若需生成源圖形變換到目標圖形中的N-1個漸變圖形,採用簡單的線性插值能夠編寫以下的二重循環:html

     for (k=1;k<N;k++)java

         for (i=0;i<M;i++)算法

         {canvas

            x=(dx[i]-sx[i])/N*k+sx[i];數組

            y=(dy[i]-sy[i])/N*k+sy[i];瀏覽器

            // 按求得的插值座標點繪製漸變圖形ide

         }函數

1.六瓣花朵漸變爲圓

六瓣花朵的笛卡爾座標方程式設定爲:動畫

    t=r1*(1+sin(18*θ)/5) *(0.5+Math.sin(6*θ)/2);

    x=t*cos(θ);

    y=t* sin(θ);       (0≤θ≤2π)

圓的笛卡爾座標方程式爲:

x=r*cos(θ)

y=r*sin(θ)         (0≤θ≤2π)

在六瓣花朵和圓上分別取128個點,而後利用簡單的線性插值繪製中間24個漸變圖形。編寫以下的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,200,200);

     context.strokeStyle="red";

     context.lineWidth=1;

     var dig=Math.PI/64;

     var x1=new Array(129);

     var y1=new Array(129);

     var x2=new Array(129);

     var y2=new Array(129);

     for (var i=0;i<=128;i++)

     {

         d=50*(1+Math.sin(18*i*dig)/5);

         t=d*(0.5+Math.sin(6*i*dig)/2);

         x1[i]=t*Math.cos(i*dig);

         y1[i]=t*Math.sin(i*dig);

         x2[i]=80*Math.cos(i*dig);

         y2[i]=80*Math.sin(i*dig);

     }

     context.beginPath();

     for (n=0;n<=25;n++)

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

         {

            x=(x2[i]-x1[i])/25*n+x1[i]+100;

            y=(y2[i]-y1[i])/25*n+y1[i]+100;

            if (i==0)

            {

              context.moveTo(x,y);

              bx=x;  by=y;

            }

            else

              context.lineTo(x,y);

          }

      context.lineTo(bx,by);

      context.closePath();

      context.stroke();

  }

</script>

</head>

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

<canvas id="myCanvas" width="200" height="200"></canvas>

</body>

</html>

將上述HTML代碼保存到一個html文本文件中,再在瀏覽器中打開包含這段HTML代碼的html文件,能夠看到在畫布中繪製出從六瓣花朵漸變爲圓的圖案,如圖1所示。

  

圖1  六瓣花朵漸變爲圓

2.圓漸變爲花朵

咱們將圖1圖形中的圓漸變爲六瓣花朵的過程動態展現出來。編寫的HTML文件內容以下。

<!DOCTYPE>

<html>

<head>

<title>圓漸變爲花朵</title>

</head>

<body>

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

</canvas>

<script type="text/javascript">

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

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

   context.fillStyle="#EEEEFF";

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

   context.fillStyle = "red";

   var dig=Math.PI/64;

   var x1=new Array(129);

   var y1=new Array(129);

   var x2=new Array(129);

   var y2=new Array(129);

   var n=0;

   for (var i=0;i<=128;i++)

   {

        d=50*(1+Math.sin(18*i*dig)/5);

        t=d*(0.5+Math.sin(6*i*dig)/2);

        x1[i]=t*Math.cos(i*dig);

        y1[i]=t*Math.sin(i*dig);

        x2[i]=80*Math.cos(i*dig);

        y2[i]=80*Math.sin(i*dig);

   }

   function draw()

   {

       context.clearRect(0,0,200,200);

       context.beginPath();

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

       {

            x=(x1[i]-x2[i])/25*n+x2[i]+100;

            y=(y1[i]-y2[i])/25*n+y2[i]+100;

            if (i==0)

            {

              context.moveTo(x,y);

              bx=x;  by=y;

            }

            else

              context.lineTo(x,y);

      }

      context.lineTo(bx,by);

      context.stroke();

      n = n+ 1;

      if (n > 25)  n= 0;

      context.fill();

   }

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

</script>

</body>

</html>

將上述HTML代碼保存到一個html文本文件中,再在瀏覽器中打開包含這段HTML代碼的html文件,能夠在畫布中看到從圓漸變爲六瓣花朵的動畫過程,如圖2所示。

 

圖2  從圓漸變爲六瓣花朵

3.六瓣花朵漸變爲正方形

仿照上面的思路,設計程序將六瓣花朵漸變爲正方形,且漸變計算時採用對數函數。編寫以下的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="#EEEEDD";

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

     context.strokeStyle="red";

     context.lineWidth=1;

     var dig=Math.PI/60;

     var x1=new Array(120);

     var y1=new Array(120);

     var x2=new Array(120);

     var y2=new Array(120);

     // 生成花瓣基本數據,座標保存在(x1[i],y1[i])中

     var petalNum=6;      // 花瓣數

     for (var i=0;i<120;i++)

     {

         d=50*(1+Math.sin(petalNum*(i*dig+Math.PI/4)));

         x1[i]=d*Math.cos(i*dig+Math.PI/4);

         y1[i]=-d*Math.sin(i*dig+Math.PI/4);

     }

     // 生成多邊形基本數據,座標保存在(x2[i],y2[i])中

     var r=150;

     var sideNum=4;     // 正多邊形邊數

     var k=120/sideNum; 

     dig=Math.PI/sideNum;

     var dd=2*r*Math.sin(dig)/k; 

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

     {

        aa=2*i*dig+3*Math.PI/4;

        x0=r*Math.sin(aa);

        y0=r*Math.cos(aa);

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

        {

           x2[i*k+j]=x0+j*dd*Math.sin(aa+Math.PI/2+Math.PI/sideNum);

           y2[i*k+j]=y0+j*dd*Math.cos(aa+Math.PI/2+Math.PI/sideNum);

        }

     }

     context.beginPath();

     // 按對數規律進行圖案漸變

     for (n=0;n<=25;n++)

     {

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

         {

            x=(x2[i]-x1[i])/Math.log(25)*Math.log(n)+x1[i]+150;

            y=(y2[i]-y1[i])/Math.log(25)*Math.log(n)+y1[i]+150;

            if (i==0)

            {

              context.moveTo(x,y);

              bx=x;  by=y;

            }

            else

              context.lineTo(x,y);

          }

          context.lineTo(bx,by);

      }

      context.closePath();

      context.stroke();

  }

</script>

</head>

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

<canvas id="myCanvas" width="320" height="320"></canvas>

</body>

</html>

將上述HTML代碼保存到一個html文本文件中,再在瀏覽器中打開包含這段HTML代碼的html文件,能夠看到在畫布中繪製出從六瓣花朵漸變爲正方形的圖案,如圖3所示。

 

圖3  從六瓣花朵漸變爲正方形

      將繪製圖3的HTML程序中的花瓣數設置爲5,正多邊形邊數也設置爲5,即修改語句「var petalNum=6;」爲「var petalNum=5;」,修改語句「var sideNum=4;」爲「var sideNum=5;」,則在畫布中繪製出如圖4所示的從五瓣花朵漸變爲正五邊形的圖案。

  

圖4  從五瓣花朵漸變爲正五邊形

4.正五邊形漸變爲五瓣花朵

咱們將圖4圖形中的正五邊形漸變爲五瓣花朵的過程動態展現出來。編寫的HTML文件內容以下。

<!DOCTYPE>

<html>

<head>

<title>正五邊形漸變爲五瓣花朵</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 context = canvas.getContext('2d');

   context.fillStyle="#EEEEFF";

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

   context.fillStyle = "red";

   var dig=Math.PI/60;

   var x1=new Array(120);

   var y1=new Array(120);

   var x2=new Array(120);

   var y2=new Array(120);

   // 生成花瓣基本數據,座標保存在(x1[i],y1[i])中

   var petalNum=5;

   for (var i=0;i<120;i++)

   {

         d=50*(1+Math.sin(petalNum*(i*dig+Math.PI/4)));

         x1[i]=d*Math.cos(i*dig+Math.PI/4);

         y1[i]=-d*Math.sin(i*dig+Math.PI/4);

   }

   // 生成多邊形基本數據,座標保存在(x2[i],y2[i])中

   var r=150;

   var sideNum=5;

   var k=120/sideNum; 

   dig=Math.PI/sideNum;

   var dd=2*r*Math.sin(dig)/k; 

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

   {

        aa=2*i*dig+3*Math.PI/4;

        x0=r*Math.sin(aa);

        y0=r*Math.cos(aa);

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

        {

           x2[i*k+j]=x0+j*dd*Math.sin(aa+Math.PI/2+Math.PI/sideNum);

           y2[i*k+j]=y0+j*dd*Math.cos(aa+Math.PI/2+Math.PI/sideNum);

        }

   }

   var n=0;

   function draw()

   {

       context.clearRect(0,0,300,300);

       context.beginPath();

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

       {

            x=(x1[i]-x2[i])/Math.log(25)*Math.log(n)+x2[i]+150;

            y=(y1[i]-y2[i])/Math.log(25)*Math.log(n)+y2[i]+150;

            if (i==0)

            {

              context.moveTo(x,y);

              bx=x;  by=y;

            }

            else

              context.lineTo(x,y);

        }

        context.lineTo(bx,by);

        context.closePath();

        context.stroke();

        n = n+ 1;

        if (n > 25)  n= 0;

        context.fill();

   }

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

</script>

</body>

</html>

將上述HTML代碼保存到一個html文本文件中,再在瀏覽器中打開包含這段HTML代碼的html文件,能夠在畫布中看到從正五邊形漸變爲五瓣花朵的動畫過程,如圖5所示。

  

圖5 正五邊形漸變爲五瓣花朵

相關文章
相關標籤/搜索