zoukankan      html  css  js  c++  java
  • JavaScript图形实例:利用插值实现图像渐变

          描述由一个图形变化为另一个图形过程中的各个中间图形,称为渐变图形。可以利用插值算法求得各个渐变图形。

          设在源图形和目标图形上各取M个对应坐标点,并分别保存到数组中,源图形用数组SX[M]和SY[M]保存M个坐标点(sx,sy),目标图形用数组DX[M]和DY[M]保存M个坐标点(dx,dy)。若需生成源图形变换到目标图形中的N-1个渐变图形,采用简单的线性插值可以编写如下的二重循环:

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

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

             {

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

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

                // 按求得的插值坐标点绘制渐变图形

             }

    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 正五边形渐变为五瓣花朵

  • 相关阅读:
    距离的总和
    [leetcode] 397. Integer Replacement
    [leetcode] 396. Rotate Function
    [leetcode] 398. Random Pick Index
    [leetcode] 399. Evaluate Division
    [算法] get_lucky_price price
    Geoserver(一) Geoserver2.15.4配置发布arcgis切片
    Geoserver(二) geoserver配置mysql插件
    OpenLayers4地图实例-功能齐全
    OpenLayers Node环境安装运行构建-支持Vue集成OpenLayers
  • 原文地址:https://www.cnblogs.com/cs-whut/p/13193830.html
Copyright © 2011-2022 走看看