分形圖的繪制

更多算法(語言為JavaScript) 持續(xù)更新...

戳我去GitHub看更多算法問題>>>>目錄

戳我去GitHub看詳細代碼>>>>分形基礎(chǔ)繪制

Vicsek fractal

基本正方形在3×3網(wǎng)格中分解為9個較小的正方形乔妈,繪制角落處的四個正方形和中間正方形租悄。對于剩余的五個子方格中的每一個真慢,遞歸地重復(fù)該過程。Vicsek分形是在此程序的極限下獲得的集合。

https://en.wikipedia.org/wiki/Vicsek_fractal
// 繪制圖形
    draw(ctx, depth = this.depth, x = 0, y = 0, w = this.width, h = this.width) {

      ctx.fillStyle = '#ccc';

      if (depth <= 0 && depth != undefined || w <= 1 || h <= 1) {
        // 繪制
        ctx.fillRect(x, y, w, h)
        return
      }

      this.depth = depth

      // 要繪制的格子容器中的小格子的寬高  將格子容器劃分為3 * 3 的矩陣 根據(jù)位置分別繪制小格子
      let w_3 = w / 3
      let h_3 = h / 3

      // 遞歸繪制每個格子的5個方向
      this.draw(ctx, depth - 1,x, y, w_3, h_3)
      this.draw(ctx, depth - 1, x + 2 * w_3, y, w_3, h_3)
      this.draw(ctx, depth - 1, x + 2 * w_3, y + 2 * w_3, w_3, h_3)
      this.draw(ctx, depth - 1, x + w_3, y + w_3, w_3, h_3)
      this.draw(ctx, depth - 1, x, y + 2 * w_3, w_3, h_3) 
    }

分形結(jié)果如下圖:


Vicsek分形.gif

Sierpinski carpet 分形

Sierpinski carpet 始于一個正方形"方形幾何"。該正方形在3×3網(wǎng)格中被切割成9個一致的子方形,只繪制中心子方躯护,然后,無限制地將相同的過程遞歸地應(yīng)用于剩余的8個子方格拔恰。


流程圖
// 繪制圖形
   draw(ctx, depth = this.depth, x = 0, y = 0, w = this.width, h = this.width) {

     ctx.fillStyle = '#fff';

     // 要繪制的格子容器中的小格子的寬高  將格子容器劃分為3 * 3 的矩陣 根據(jù)位置分別繪制小格子
     let w_3 = w / 3
     let h_3 = h / 3

     if (depth <= 0 && depth != undefined || w <= 1 || h <= 1) return

     this.depth = depth


     // 遞歸繪制9個格子
     for (let i = 0; i < 3; i++) {
       for (let j = 0; j < 3; j++) {
         if (i === 1 && j === 1) {
           // 中心的格子 直接繪制
           ctx.fillRect( x + w_3, y + w_3, w_3, h_3)
         } else {
           // 其他八個角的格子 遞歸
           this.draw(ctx, depth - 1, x + i * w_3, y + j * w_3, w_3, h_3)
         }
       }
     }
   }

分形結(jié)果如下圖:


sierpinski_carpet_分形.gif

sierpinski triangle 分形

  • 從等邊三角形開始夹厌。
  • 將其細分為四個較小的全等邊三角形并移除中心三角形。
  • 重復(fù)步驟2,永遠保留每個剩余的較小三角形恢氯。


    sierpinski triangle 分形

    思路
    // 繪制圖形
    draw(ctx, depth = this.depth, Ax = 0, Ay = this.side, side = this.side, all = this.depth) {

      ctx.fillStyle = '#ccc';
      // 計算三角形其余兩點坐標
      let Bx = Ax + side
      let By = Ay
      let Cx = Ax + side / 2
      let Cy = Ay - Math.sin( 2 * Math.PI / 360 * 60) * side

      if (depth <= 0 && depth != undefined || side <= 1) {
        // 傳入三點坐標
        this.triangle(ctx, Ax, Ay,Bx, By, Cx, Cy)
        return
      }

      // 遞歸 在左下角坐標為 (Ax, Ay)且邊長為 side 的正方形中繪制三個等邊三角形
      this.draw(ctx, depth - 1, Ax, Ay, side / 2, all)
      this.draw(ctx, depth - 1, (Ax + Bx) / 2, (Ay + By) / 2, side / 2, all)
      this.draw(ctx, depth - 1, (Ax + Cx) / 2, (Ay + Cy) / 2, side / 2, all)

    }
    // 繪制三角形 傳入三點的坐標
    triangle(ctx, x1, y1, x2, y2, x3, y3) {
      ctx.beginPath()
      ctx.moveTo(x1, y1);
      ctx.lineTo(x2, y2);
      ctx.lineTo(x3, y3);
      ctx.closePath();
      ctx.fill();
    }

分形結(jié)果如下圖:


sierpinski_triangle_分形.gif

koch snowflake 分形

概念:Koch雪花可以通過等邊三角形開始構(gòu)建,然后遞歸地改變每個線段程腹,如下所示:

  • 將線段劃分為三個相等長度的段
  • 繪制一個等邊三角形嚼吞,其中以第1步的中間部分作為基準,并指向外部刽严。
  • 從第2步中刪除作為三角形底邊的線段昂灵。

在該過程的一次迭代之后避凝,得到的形狀是六芒星的輪廓。

koch snowflake 分形
思路
    // 繪制圖形
    draw(ctx, depth = this.depth, x1 = 0, y1 = this.width / 2, side = this.width, deg = 0) {

      ctx.strokeStyle = '#fff';

      // 要繪制的格子容器中的小格子的寬高  將格子容器劃分為3 * 3 的矩陣 根據(jù)位置分別繪制小格子
      let w_3 = side / 3

      if (depth < 0 && depth != undefined || w_3 <= 1) {
        let x2 = x1 + Math.cos(2 * Math.PI / 360 * deg) * side
        let y2 = y1 - Math.sin(2 * Math.PI / 360 * deg) * side
        this.line(ctx, x1, y1, x2, y2)
        return
      }

      let x2 = x1 + Math.cos(2 * Math.PI / 360 * deg) * w_3
      let y2 = y1 - Math.sin(2 * Math.PI / 360 * deg) * w_3
      this.draw(ctx, depth - 1, x1, y1, w_3, deg)

      let x3 = x2 + w_3 * Math.cos(2 * Math.PI / 360 * (deg + 60))
      let y3 = y2 - w_3 * Math.sin(2 * Math.PI / 360 * (deg + 60))
      this.draw(ctx, depth - 1, x2, y2, w_3, deg + 60)

      let x4 = x3 + w_3 * Math.cos(2 * Math.PI / 360 * (deg - 60))
      let y4 = y3 - w_3 * Math.sin(2 * Math.PI / 360 * (deg - 60))
      this.draw(ctx, depth - 1, x3, y3, w_3, deg - 60)

      this.draw(ctx, depth - 1, x4, y4, w_3, deg)
    }

    // 繪制線條
    line(ctx, x1, y1, x2, y2) {
      ctx.beginPath();
      ctx.moveTo(x1, y1);
      ctx.lineTo(x2, y2);
      ctx.closePath();
      ctx.stroke();
    }

分形結(jié)果如下圖:


koch_snowflake_分形.gif

分形繪制樹??

   
   // 繪制圖形
   draw(ctx, depth = this.depth, x1 = this.width / 2, y1 = this.width, side = this.width, deg = 0) {

     ctx.strokeStyle = '#fff';
     let w_2 = side / 2

     if (depth < 0 && depth != undefined || w_2 <= 1) {
       let x2 = x1 - Math.sin(2 * Math.PI / 360 * deg) * side
       let y2 = y1 - Math.cos(2 * Math.PI / 360 * deg) * side
       this.line(ctx, x1, y1, x2, y2)
       return
     }


     // 獲取中點坐標
     let x2 = x1 - Math.sin(2 * Math.PI / 360 * deg) * w_2
     let y2 = y1 - Math.cos(2 * Math.PI / 360 * deg) * w_2

     // 下邊的樹杈
     this.line(ctx, x1, y1, x2, y2)
     // 左邊的樹杈
     this.draw(ctx, depth - 1, x2, y2, w_2, deg + this.splitDeg / 2)
     // 右邊的樹杈
     this.draw(ctx, depth - 1, x2, y2, w_2, deg - this.splitDeg / 2)
   }

   // 繪制線條
   line(ctx, x1, y1, x2, y2) {
     ctx.beginPath();
     ctx.moveTo(x1, y1);
     ctx.lineTo(x2, y2);
     ctx.closePath();
     ctx.stroke();
   }

分形結(jié)果如下圖:


繪制樹_分形.gif
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末眨补,一起剝皮案震驚了整個濱河市管削,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌撑螺,老刑警劉巖含思,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異甘晤,居然都是意外死亡含潘,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門线婚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來遏弱,“玉大人,你說我怎么就攤上這事塞弊∈荩” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵居砖,是天一觀的道長虹脯。 經(jīng)常有香客問我,道長奏候,這世上最難降的妖魔是什么循集? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮蔗草,結(jié)果婚禮上咒彤,老公的妹妹穿的比我還像新娘。我一直安慰自己咒精,他們只是感情好镶柱,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著模叙,像睡著了一般歇拆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上范咨,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天故觅,我揣著相機與錄音,去河邊找鬼渠啊。 笑死输吏,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的替蛉。 我是一名探鬼主播贯溅,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼拄氯,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了它浅?” 一聲冷哼從身側(cè)響起译柏,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎姐霍,沒想到半個月后艇纺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡邮弹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年黔衡,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腌乡。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡盟劫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出与纽,到底是詐尸還是另有隱情侣签,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布急迂,位于F島的核電站影所,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏僚碎。R本人自食惡果不足惜猴娩,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望勺阐。 院中可真熱鬧卷中,春花似錦、人聲如沸渊抽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽懒闷。三九已至十减,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間愤估,已是汗流浹背帮辟。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留灵疮,地道東北人织阅。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓壳繁,卻偏偏與公主長得像震捣,于是被迫代替她去往敵國和親荔棉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容