JavaScript圖形實例:像雪花一樣的Hexaflake分形

来源:https://www.cnblogs.com/cs-whut/archive/2020/07/07/13259351.html
-Advertisement-
Play Games

編寫如下的函數: function drawHexagon(x,y,L) { ctx.beginPath(); ctx.moveTo(x-sqrt3/2*L,y-L/2); ctx.lineTo(x-sqrt3/2*L,y+L/2); ctx.lineTo(x,y+L); ctx.lineTo(x+ ...


      編寫如下的函數:

   function drawHexagon(x,y,L)

   {

        ctx.beginPath();

        ctx.moveTo(x-sqrt3/2*L,y-L/2);

        ctx.lineTo(x-sqrt3/2*L,y+L/2);

        ctx.lineTo(x,y+L);

        ctx.lineTo(x+sqrt3/2*L,y+L/2);

        ctx.lineTo(x+sqrt3/2*L,y-L/2);

        ctx.lineTo(x,y-L);

        ctx.closePath();

        ctx.fillStyle = "#00FFFF";

        ctx.fill();

   }

      函數中sqrt3的值為Math.sqrt(3)。該函數的功能是:以坐標(x,y)為中心點,繪製一個邊長為L的正六邊形併進行填充,如圖1所示。

 

圖1 正六邊形

      編寫如下的調用語句:

   var x=250;

   var y=250;

   var L=200;

   drawHexagon(x,y-2*L/3,L/3);

   drawHexagon(x,y,L/3);

   drawHexagon(x,y+2*L/3,L/3);

   drawHexagon(x-sqrt3/3*L,y+L/3,L/3);

   drawHexagon(x-sqrt3/3*L,y-L/3,L/3);

   drawHexagon(x+sqrt3/3*L,y+L/3,L/3);

   drawHexagon(x+sqrt3/3*L,y-L/3,L/3);

      可以繪製出如圖2所示的7個小正六邊形,這7個小正六邊形正好填充在以(x,y)為中心邊長為L的大正六邊形中。

 

圖2  7個正六邊形組成的圖案

      Hexaflake分形圖案的構造過程是:以(x,y)為中心點繪製一個邊長為L的正六邊形併進行顏色填充;在這個正六邊形中找到7個點,以這7個點為中心分別繪製7個邊長為L/3的正六邊形併進行顏色填充,替換掉原來邊長為L的正六邊形;重覆以上操作直至達到要求的層數,可以繪製出Hexaflake分形圖案,如圖3所示。

圖3  Hexaflake分形圖案的生成

      Hexaflake分形採用遞歸過程易於實現,編寫如下的HTML代碼。

<!DOCTYPE html>

<head>

<title>Hexaflake分形</title>

</head>

<body>

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

</canvas>

<script type="text/javascript">

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

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

   var maxdepth =4;

   var sqrt3=Math.sqrt(3);

   function drawHexagon(x,y,L)

   {

        ctx.beginPath();

        ctx.moveTo(x-sqrt3/2*L,y-L/2);

        ctx.lineTo(x-sqrt3/2*L,y+L/2);

        ctx.lineTo(x,y+L);

        ctx.lineTo(x+sqrt3/2*L,y+L/2);

        ctx.lineTo(x+sqrt3/2*L,y-L/2);

        ctx.lineTo(x,y-L);

        ctx.closePath();

        ctx.fillStyle = "#00FFFF";

        ctx.fill();

   }

   function drawHexaflake(n,x,y,L)

   {

        if(n>0)

        {

            drawHexaflake(n-1,x,y-2*L/3,L/3);

            drawHexaflake(n-1,x,y,L/3);

            drawHexaflake(n-1,x,y+2*L/3,L/3);

            drawHexaflake(n-1,x-sqrt3/3*L,y+L/3,L/3);

            drawHexaflake(n-1,x-sqrt3/3*L,y-L/3,L/3);

            drawHexaflake(n-1,x+sqrt3/3*L,y+L/3,L/3);

            drawHexaflake(n-1,x+sqrt3/3*L,y-L/3,L/3);

        }

        else

            drawHexagon(x,y,L);

   }

   drawHexaflake(maxdepth,250,250,200);

</script>

</body>

</html>

       在瀏覽器中打開包含這段HTML代碼的html文件,可以看到在瀏覽器視窗中繪製出的Hexaflake分形圖案,如圖4所示。

圖4  遞歸深度maxdepth =4的Hexaflake分形

      執行語句:   ctx.fillStyle="black";

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

      將屏幕背景設置為黑色,將繪製的正六邊形用白色填充,則在瀏覽器視窗中繪製出的Hexaflake分形圖案像雪花兒一樣,如圖5所示。

圖5  像雪花一樣的Hexaflake分形

      將Hexaflake分形的生成過程進行動態展示,編寫如下的HTML文件。

<!DOCTYPE html>

<head>

<title>Hexaflake分形</title>

</head>

<body>

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

</canvas>

<script type="text/javascript">

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

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

   var depth =0;

   var sqrt3=Math.sqrt(3);

   function drawHexagon(x,y,L)

   {

        ctx.beginPath();

        ctx.moveTo(x-sqrt3/2*L,y-L/2);

        ctx.lineTo(x-sqrt3/2*L,y+L/2);

        ctx.lineTo(x,y+L);

        ctx.lineTo(x+sqrt3/2*L,y+L/2);

        ctx.lineTo(x+sqrt3/2*L,y-L/2);

        ctx.lineTo(x,y-L);

        ctx.closePath();

        ctx.fillStyle = "#FFFFFF";

        ctx.fill();

   }

   function drawHexaflake(n,x,y,L)

   {

        if(n>0)

        {

            drawHexaflake(n-1,x,y-2*L/3,L/3);

            drawHexaflake(n-1,x,y,L/3);

            drawHexaflake(n-1,x,y+2*L/3,L/3);

            drawHexaflake(n-1,x-sqrt3/3*L,y+L/3,L/3);

            drawHexaflake(n-1,x-sqrt3/3*L,y-L/3,L/3);

            drawHexaflake(n-1,x+sqrt3/3*L,y+L/3,L/3);

            drawHexaflake(n-1,x+sqrt3/3*L,y-L/3,L/3);

        }

        else

            drawHexagon(x,y,L);

   }

   function go()

   {

        ctx.fillStyle = "#000000";

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

        drawHexaflake(depth,250,250,200);

        depth++;

        if (depth>4)

        {

           depth=0;

        }

   }

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

</script>

</body>

</html>

      在瀏覽器中打開包含這段HTML代碼的html文件,在瀏覽器視窗中呈現出如圖6所示的Hexaflake分形動態生成效果。

 

圖6  Hexaflake分形圖案動態生成


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

-Advertisement-
Play Games
更多相關文章
  • 您聽說過bilibili嗎?如果您居住在中國或對宅男文化感興趣,那麼您可能會感興趣。對於那些不瞭解Bilibili的人來說,這是一個視頻共用網站。大部分視頻都位於中國,其主題是動畫,漫畫和游戲。 Bilibili是目前YouTube上最好的替代產品之一,如果您喜歡卡通漫畫,可以依靠它。您會在那找到超 ...
  • 寫在前面 最近身邊有不少朋友想轉行去做前端開發,然後跑過來問我,向我瞭解前端崗位,以及給他們一些建議等等;他們有的還沒畢業,對於即將到來的社會毒打充滿著迷茫和不安,有的已經工作兩三年,突然覺得自己不合適當下這個份工作,想謀求一份別的職業。 選擇一份職業不在於這份職業可以給你帶來什麼,而是你可以因此成 ...
  • 一、繪製矩形 1、rect (x, y, width, height) : 繪製矩形的路徑 用軌跡畫的,不是獨立路徑( 沒有beginPath() ) 需要stroke()描邊才會顯示 2、strokeRect (x, y, width, height) : 描邊矩形 自動描邊,有獨立路徑 3、fi ...
  • 只能在render函數裡面使用JSX嗎 當然不是,你可以定義method,然後在method裡面返回JSX,然後在render函數裡面調用這個方法,不僅如此,JSX還可以直接賦值給變數,比如下麵這段代碼 methods: { $_renderFooter() { return ( <div> <El ...
  • 是時候使用JSX代替createElement了 接著上面的講,當我們看到上面用createElement去實現組件,太麻煩了,別說工作效率提高了,就是那些嵌套可以嵌套正確就很贊了,所以我們需要用JSX去簡化整個邏輯。當年我做項目的時候就遇到過這樣的情況,嵌套太多,自己都快搞不明白了,在崩潰的邊緣。 ...
  • HTML——超文本標記語言 HTMl裡面有標簽,標簽又分為單標簽和雙標簽,也分為行級元素和塊級元素 標簽是用<>包裹起來的,而且必須要有<>,否則會直接顯示在瀏覽器上面哦 現在介紹一下常用標簽 我們還要區分行級元素和塊級元素,塊級元素的特點是獨占一行,可以設置寬高,行級元素不能設置寬高,如果需要設置 ...
  • 學習JSX,先瞭解一下createElement 提到JSX,不可避免的就要提到createElement,當你看完本節,你會發現,奇怪的知識又增多了。ok,我們接著上一部分繼續講。這一次的準備工作是瞭解createElement。 從Vue編譯後的代碼看createElement 你是否看過寫的V ...
  • 1.前景怎麼樣? web前端人才需求還會持續增加 據國內權威數據統計,未來五年,我國信息化人才總需求量高達1500萬—2000萬人。其中“網路工程”“UI設計”“web前端”等人才的缺口最為突出,所以2020年web前端的市場需求還是很大的。更有甚者,目前不僅大型互聯網公司擬相繼成立了專屬的web ...
一周排行
    -Advertisement-
    Play Games
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...