JavaScript圖形實例:再談曲線方程

来源:https://www.cnblogs.com/cs-whut/archive/2020/06/26/13193819.html
-Advertisement-
Play Games

在“JavaScript圖形實例:曲線方程”一文中,我們給出了15個曲線方程繪製圖形的實例。在本文中,我們繼續討論一下曲線方程。在本文中,我們討論的方法時,先給出一個繪製特定圖案的曲線方程,然後將方程中的一些取值參數化,然後看看這些參數取不同值時會繪製出怎樣的圖形,從而通過試探加猜測的方式找出一些繪 ...


      在“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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 目前跨端開發比較熱門的就是 React Native 和 Flutter 了,到底該選哪門技術似乎也快成了大前端圈的一個熱門話題。對於web前端來說,基於web生態的 React Native 應該是一個更加順暢而自然的選擇;但 Flutter 讓人動心的地方就是高性能和 跨端UI一致性。而Reac ...
  • 瞭解表單及其控制項 1.form:表單標簽 表單屬性: action:表單提交到哪裡 method:以什麼方式去提交到action指定的地址,有get和post,預設為get target: placeholder:表示在文本裡面預設顯示什麼文字 2.form裡面含有的控制項: input: selec ...
  • var start = "2020-6-26 20:36:00"; //開始時間 var now = new Date(); //當前時間 var ns = new Date(start).getTime() - now.getTime(); //毫秒差 //時間差 var todays = fun ...
  • /** * 多個關鍵詞列表高亮(word_list1,color1,word_list2,color2,...) * @param word_list 關鍵詞列表(例: ["關鍵詞a","關鍵詞b"],不區分大小寫) * @param color 顏色值(例: "#ff0000") * @retur ...
  • 普利姆演算法(加點法)求最小生成樹 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> ...
  • 我們在進行vue開發時會將公共的部分進行抽象,然後生成一個獨立的組件,這個組件可以被其它頁面引用,如果希望有交互的動作就設計到了值的傳遞,或者方法的回調等問題,這一次我們主要來說一下父組件和子組件的交互。 值的傳遞 子組件,通過定義了prods,然後可以實現從父組件向子組件的傳遞: <templat ...
  • 前言 computed 在 Vue 中是很常用的屬性配置,它能夠隨著依賴屬性的變化而變化,為我們帶來很大便利。那麼本文就來帶大家全面理解 computed 的內部原理以及工作流程。 在這之前,希望你能夠對響應式原理有一些理解,因為 computed 是基於響應式原理進行工作。如果你對響應式原理還不是 ...
  • 描述由一個圖形變化為另一個圖形過程中的各個中間圖形,稱為漸變圖形。可以利用插值演算法求得各個漸變圖形。 設在源圖形和目標圖形上各取M個對應坐標點,並分別保存到數組中,源圖形用數組SX[M]和SY[M]保存M個坐標點(sx,sy),目標圖形用數組DX[M]和DY[M]保存M個坐標點(dx,dy)。若需生 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...