• JavaScript图形实例:再谈曲线方程


          在“JavaScript图形实例:曲线方程”一文中,我们给出了15个曲线方程绘制图形的实例。在本文中,我们继续讨论一下曲线方程。在本文中,我们讨论的方法时,先给出一个绘制特定图案的曲线方程,然后将方程中的一些取值参数化,然后看看这些参数取不同值时会绘制出怎样的图形,从而通过试探加猜测的方式找出一些绘制精美曲线图案的曲线方程。

    1.四叶花瓣线

    四叶花瓣线的笛卡尔坐标方程式设定为:

        x=r*cos(2θ)*sin(θ)

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

    编写如下的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,300,300);

         context.strokeStyle="red";

         context.lineWidth=2;

         context.save();

         context.translate(150,150);

         var r=120;

         context.beginPath();

         for (theta=0;theta<=2*Math.PI;theta+=Math.PI/100)

         {

            var x = r*Math.cos(2*theta)*Math.sin(theta);

            var y = r*Math.cos(2*theta)*Math.cos(theta);

            if (theta==0)

               context.moveTo(x,y);

            else

               context.lineTo(x,y);

          }

         context.stroke();

         context.restore();

       }

    </script>

    </head>

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

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

    </body>

    </html>

    将上述HTML代码保存到一个html文本文件中,再在浏览器中打开包含这段HTML代码的html文件,可以看到在画布中绘制出四叶花瓣线图案,如图1所示。

      

    图1  4叶花瓣线

    下面将四叶花瓣线的笛卡尔坐标方程式参数化为:

        x=r*cos(nθ)*sin(θ)

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

    编写程序,在画布中绘制出n=1~10时的图案。编写的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,510,210);

         context.strokeStyle="red";

         context.lineWidth=2;

         n=0;

         r=45;

         for (py=50;py<=150;py+=100)

           for (px=50;px<=450;px+=100)

           {

               n++; 

               context.beginPath();

               for (theta=0;theta<=2*Math.PI;theta+=Math.PI/100)

               {

                   var x = r*Math.cos(n*theta)*Math.sin(theta)+px;

                   var y = r*Math.cos(n*theta)*Math.cos(theta)+py;

                   if (theta==0)

                      context.moveTo(x,y);

                   else

                      context.lineTo(x,y);

                }

                context.stroke();

            }

       }

    </script>

    </head>

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

    <canvas id="myCanvas" width="510" height="210"></canvas>

    </body>

    </html>

    将上述HTML代码保存到一个html文本文件中,再在浏览器中打开包含这段HTML代码的html文件,可以看到在画布中绘制出如图2所示花瓣线图案。

      

    图2 花瓣线图案

          图2中的10个图案从上到下,从左往右对应着N取值为1~10时的情况。由图2可知,当N为奇数时,花卉线为N瓣;当N为偶数时,花瓣线为2*N瓣。

          能否给定N就绘制N瓣花呢?

    将坐标方程修改如下:

        x = r*(1/2+1/2*sin(nθ))*cos(θ)

        y = r*(1/2+1/2*sin(nθ))*sin(θ)      (0≤θ≤2π)

    编写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,510,210);

         context.strokeStyle="red";

         context.lineWidth=2;

         n=0;

         r=45;

         for (py=50;py<=150;py+=100)

           for (px=50;px<=450;px+=100)

           {

               n++; 

               context.beginPath();

               for (theta=0;theta<=2*Math.PI;theta+=Math.PI/100)

               {

                   var x = r*(1/2+1/2*Math.sin(n*theta))*Math.cos(theta)+px;

                   var y = r*(1/2+1/2*Math.sin(n*theta))*Math.sin(theta)+py;

                   if (theta==0)

                      context.moveTo(x,y);

                   else

                      context.lineTo(x,y);

                }

                context.stroke();

            }

       }

    </script>

    </head>

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

    <canvas id="myCanvas" width="510" height="210"></canvas>

    </body>

    </html>

    将上述HTML代码保存到一个html文本文件中,再在浏览器中打开包含这段HTML代码的html文件,可以看到在画布中绘制出如图3所示的N(N为1~10)叶花瓣线图案。

      

    图3  N叶花瓣线图案

    我们还可以将四叶花瓣线的笛卡尔坐标方程式参数化为:

    x=r*(1/5*sin(n*p*θ)+sin(n*θ))*cos(θ)

    y=r*(1/5*sin(n*p*θ)+sin(n*θ))*sin(θ)         (0≤θ≤2π)

    编写如下的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,300,300);

         context.strokeStyle="red";

         context.lineWidth=2;

         context.beginPath();

         var r=100;

         var n=eval(document.myForm.petalNum.value);

         if (n%2==0 && n%4!=0)

         {

            alert("花瓣数如果是偶数,必须是4的倍数!");

            return;

         }

         if (n%2==0) n=n/2;

         var p=eval(document.myForm.shape.value);

         for (theta=0;theta<=2*Math.PI;theta+=Math.PI/180)

         {

             x=150+r*(1/5*Math.sin(n*p*theta)+Math.sin(n*theta))*Math.cos(theta);

             y=150+r*(1/5*Math.sin(n*p*theta)+Math.sin(n*theta))*Math.sin(theta);

             if (theta==0)

                context.moveTo(x,y);

             else

                context.lineTo(x,y);

         }

         context.stroke();

       }

    </script>

    </head>

    <body>

    <form name="myForm">

    花瓣数<input type=number name="petalNum" value=4 size=3><br>

    花形:<input type=number name="shape" value=1 size=3>

    <input type=button value="确定" onClick="draw('myCanvas');">

    </form><br>

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

    </body>

    </html>

    在浏览器中打开包含这段HTML代码的html文件,可以看到在画布中绘制出如图4所示的花卉线图案。

     

    图4  可设置参数的N瓣花卉图

          由图4可以看出,由于参数方程中和一个正弦P次波进行了合成,因此花卉的花瓣形状会发生改变。

    2.花型图案

    根据参数方程:

        x=r*(sin(n*0.5*θ)/3+sin(n*θ))*cos(2*θ)

        y=r*(sin(n*0.5*θ)/3+sin(n*θ))*sin(2*θ)       (0≤θ≤2π)

    编写的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,500,210);

         context.strokeStyle="red";

         context.lineWidth=1;

         context.beginPath();

         n=0;

         b=35;

         for (py=50;py<=150;py+=100)

           for (px=50;px<=450;px+=100)

           {

               n++; 

               for (theta=0;theta<=2*Math.PI;theta+=Math.PI/128)

               {

                  r=b/3*Math.sin(n*0.5*theta)+b*Math.sin(n*theta);

                  x=px+r*Math.cos(2*theta);

                  y=py+r*Math.sin(2*theta);

                  if (theta==0)

                  {

                    context.moveTo(x,y);

                    bx=x;  by=y;

                  }

                  else

                    context.lineTo(x,y);

               }

               context.lineTo(bx,by);

               context.stroke();

          }

       }

    </script>

    </head>

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

    <canvas id="myCanvas" width="500" height="210"></canvas>

    </body>

    </html>

    将上述HTML代码保存到一个html文本文件中,再在浏览器中打开包含这段HTML代码的html文件,可以在画布中绘制出N=1~10的10种花型图案,如图5所示。

      

    图5  花型图案1

          先将上面代码中的语句“x=px+r*Math.cos(2*theta);”和“y=py+r*Math.sin(2*theta);”中的“2*theta”均修改为“4*theta”,则在画布中绘制出如图6所示的图案;若再将语句“r=b/3*Math.sin(n*0.5*theta)+b*Math.sin(n*theta);”中的“n*0.5*theta”修改为“n*theta”,则在画布中绘制出如图7所示的图案。

      

    图6  花型图案2

      

    图7  花型图案3

          在这30个图案中,有你喜欢的吗?

    3.曲线图案1

    根据参数方程:

        x=r*sin(n*θ)*cos(5*θ)

        y=r*sin((n+k)*θ)*sin(5*θ)       (0≤θ≤2π)

    编写的HTML文件内容如下。

    <!DOCTYPE html>

    <head>

    <title>曲线图案1</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,500,500);

         context.strokeStyle="red";

         context.lineWidth=1;

         context.beginPath();

         n=0;

         r=45;

         for (py=50;py<=450;py+=100)

         {

             n=n+2;

             k=0;  

             for (px=50;px<=450;px+=100)

             {

               k++; 

               for (theta=0;theta<=2*Math.PI;theta+=Math.PI/64)

               {

                  x=px+r*Math.sin(n*theta)*Math.cos(5*theta);

                  y=py+r*Math.sin((k+n)*theta)*Math.sin(5*theta);

                  if (theta==0)

                  {

                    context.moveTo(x,y);

                    bx=x;  by=y;

                  }

                  else

                    context.lineTo(x,y);

               }

               context.lineTo(bx,by);

               context.stroke();

            }

         }

       }

    </script>

    </head>

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

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

    </body>

    </html>

    将上述HTML代码保存到一个html文本文件中,再在浏览器中打开包含这段HTML代码的html文件,可以看到在画布中绘制出的曲线图案1-1,如图8所示。

           在图8中绘制了5行5列共25个曲线图案。其中,第1行是参数方程中n取值为2,k取值依次为1,2,3,4,5的5个图案;第2行是参数方程中n取值为4,k取值依次为1,2,3,4,5的5个图案;……;第5行是参数方程中n取值为10,k取值依次为1,2,3,4,5的5个图案。

     

    图8  曲线图案1-1            

          绘制图8程序中,求x和y坐标的语句中,均有“5*theta”,这里“5”作为倍数(不妨设为参数p)也可以修改。例如,修改两语句中的“5*theta”为“theta”,则在画布中绘制出如图9所示的曲线图案1-2。修改两语句中的“5*theta”为“2*theta”,则在画布中绘制出如图10所示的曲线图案1-3。

      

    图9  曲线图案1-2

     

    图10  曲线图案1-3

          再如,直接修改绘制图8程序代码中的语句“var n=0;”为“var n=1;”,其余部分不变,则在画布中绘制出如图11所示的曲线图案4。这些图案是N分别取3,5,7,9,11,k分别取1~5,p取5时所对应的曲线图案。

     

    图11 曲线图案1-4

          对照图8、9、10、11,通过修改n、k和p,你会找到你喜欢的图案吗?

    4.曲线图案2

    修改曲线图案1中的参数方程为:

        x= r*sin((n+k)*θ)*cos(p*θ)

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

    编写的HTML文件内容如下。

    <!DOCTYPE html>

    <head>

    <title>曲线图案2</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,500,500);

         context.fillStyle="blue";

         context.strokeStyle="red";

         context.lineWidth=1;

         context.beginPath();

         n=0;

         r=45;

         p=1;

         for (py=50;py<=450;py+=100)

         {

             n=n+1;  k=0;  

             for (px=50;px<=450;px+=100)

             {

               k++; 

               for (theta=0;theta<=2*Math.PI;theta+=Math.PI/64)

               {

                  x=px+r*Math.sin((k+n)*theta)*Math.cos(p*theta);

                  y=py+r*Math.sin(n*theta)*Math.sin(p*theta);

                  if (theta==0)

                  {

                    context.moveTo(x,y);

                    bx=x;  by=y;

                  }

                  else

                    context.lineTo(x,y);

               }

               context.lineTo(bx,by);

               context.stroke();

            }

         }

       }

    </script>

    </head>

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

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

    </body>

    </html>

    将上述HTML代码保存到一个html文本文件中,再在浏览器中打开包含这段HTML代码的html文件,可以看到在画布中绘制出的曲线图案2-1,如图12所示。

    在图12中绘制了5行5列共25个曲线图案。其中,第i行第j列的曲线图案对应参数值n=i,k=j。

      

    图12  曲线图案2-1

          直接修改绘制图12程序代码中的语句“p=1;”为“p=4;”,其余部分不变,则在画布中绘制出如图13所示的曲线图案2-2。

     

    图13  曲线图案2-2

  • 相关阅读:
    括号匹配的检验
    学习过程中遇到的比较有价值的博客--整理
    Spring+SpringMVC+MyBatis的pom.xml依赖
    Hibernate内容详解
    Struts2的拦截器配置
    Maven构建Struts2项目
    Mybatis增删改查,Demo整合
    简单Java类 全网最详细讲解 !!!
    Javaoop 遇到的问题
    Bootstrap 前端框架 遇到的问题 解决方案
  • 原文地址:https://www.cnblogs.com/cs-whut/p/13193819.html
Copyright © 2020-2023  润新知