Python?分形算法代碼詳解
1. 前言
分形幾何是幾何數(shù)學中的一個分支,也稱大自然幾何學,由著名數(shù)學家本華曼德勃羅( 法語:BenoitB.Mandelbrot)在 1975 年構思和發(fā)展出來的一種新的幾何學。
分形幾何是對大自然中微觀與宏觀和諧統(tǒng)一之美的發(fā)現(xiàn),分形幾何最大的特點:
- 整體與局部的相似性: 一個完整的圖形是由諸多相似的微圖形組成,而整體圖形又是微圖形的放大。
局部是整體的縮影,整體是局部的放大。
- 具有自我疊加性: 整體圖形是由微圖形不斷重復疊加構成,且具有無限疊加能力。
什么是分形算法?
所謂分形算法就是使用計算機程序模擬出大自然界的分形幾何圖案,是分形幾何數(shù)學與計算機科學相融合的藝術。
由于分形圖形相似性的特點,分形算法多采用遞歸實現(xiàn)。
2. 分形算法
2.1 科赫雪花
科赫雪花是由瑞典數(shù)學家科赫在 1904 年提出的一種不規(guī)則幾何圖形,也稱為雪花曲線。
分形圖形的特點是整體幾何圖形是由一個微圖形結(jié)構自我復制、反復疊加形成,且最終形成的整體圖案和微圖形結(jié)構一樣。在編寫分形算法時,需要先理解微圖案的生成過程。
科赫雪花的微圖案生成過程:
- 先畫一條直線??坪昭┗ū举|(zhì)就由一條直線演化而成。
- 三等分畫好的直線。
- 取中間線段,然后用夾角為 60° 的兩條等長線段替代。
- 可在每一條線段上都采用如上方式進行迭代操作,便會構造出多層次的科赫雪花。
科赫微圖形算法實現(xiàn):
使用 Python 自帶小海龜模塊繪制,科赫雪花遞歸算法的出口的是畫直線。
import turtle ''' size:直線的長度 level: 科赫雪花的層次 ''' def koch(size, level): if n == 1: turtle.fd(size) else: for i in [0, 60, -120, 60]: turtle.left(i) # 旋轉(zhuǎn)后,再繪制 koch(size // 3, level - 1)
參數(shù)說明:
- size: 要繪制的直線長度。
- level: 科赫雪花的層次。
0 階和 1 階 科赫雪花遞歸流程:
import turtle turtle.speed(100) def ke_line(line_, n): if n == 0: turtle.fd(line_) else: line_len = line_ // 3 for i in [0, 60, -120, 60]: turtle.left(i) ke_line(line_len, n - 1) # 原始直線長度 line = 300 # 移動小海龜?shù)疆嫴甲笙陆? turtle.penup() turtle.goto(-150, -150) turtle.pendown() # 1 階科赫雪花 di_gui_deep = 1 ke_line(line, di_gui_deep) turtle.done()
2 階科赫雪花:
可以多畫幾個科赫雪花,布滿整個圓周。
import turtle turtle.speed(100) def ke_line(line_, n): if n == 0: turtle.fd(line_) else: line_len = line_ // 3 for i in [0, 60, -120, 60]: turtle.left(i) ke_line(line_len, n - 1) # 原始線長度 line = 300 # 移動小海龜畫布左下角 turtle.penup() turtle.goto(-150, -150) turtle.pendown() # 幾階科赫雪花 di_gui_deep = int(input("請輸入科赫雪花的階數(shù):")) while True: # 當多少科赫雪花圍繞成一個圓周時,就構成一個完整的雪花造型 count = int(input("需要幾個科赫雪花:")) if 360 % count != 0: print("請輸入 360 的倍數(shù)") else: break for i in range(count): ke_line(line, di_gui_deep) turtle.left(360 // count) turtle.done()
4 個 3 階科赫雪花: 每畫完一個后旋轉(zhuǎn) 90 度,然后再繪制另一個。
6 個 3 階科赫雪花: 每畫完一個后,旋轉(zhuǎn) 60 度再畫另一個。
科赫雪花的繪制并不難,本質(zhì)就是畫直線、旋轉(zhuǎn)、再畫直線……
2.2 康托三分集
由德國數(shù)學家格奧爾格·康托爾在1883年引入,是位于一條線段上的一些點的集合。最常見的構造是康托爾三分點集,由去掉一條線段的中間三分之一得出。
構造過程:
- 繪制一條給定長度的直線段,將它三等分,去掉中間一段,留下兩段。
- 再將剩下的兩段再分別三等分,同樣各去掉中間一段,剩下更短的四段……
- 將這樣的操作一直繼續(xù)下去,直至無窮,由于在不斷分割舍棄過程中,所形成的線段數(shù)目越來越多,長度越來越小,在極限的情況下,得到一個離散的點集,稱為康托爾點集。
編碼實現(xiàn): 使用遞歸實現(xiàn)。
import turtle '''' (sx,sy)線段的開始位置 (ex,ey)線段的結(jié)束位置 ''' turtle.speed(100) turtle.pensize(2) def draw_kt(sx, sy, ex, ey): turtle.penup() # 小海龜移動開始位置 turtle.goto(sx, sy) turtle.pendown() # # 小海龜移動結(jié)束位置 turtle.goto(ex, ey) # 起始點與結(jié)束點之間的距離 length = ex - sx # 如果直線長線大于 5 則繼續(xù)畫下去 if length > 5: # 左邊線段的開始 x 坐標 left_sx = sx # y 坐標向下移動 30 left_sy = sy - 50 # 左邊線段的結(jié)束坐標 left_ex = sx + length / 3 left_ey = left_sy # 右邊線段的開始坐標 right_sx = ex - length / 3 right_sy = ey - 50 # 右邊線段的結(jié)束坐標 right_ex = ex right_ey = right_sy draw_kt(left_sx, left_sy, left_ex, left_ey) draw_kt(right_sx, right_sy, right_ex, right_ey) draw_kt(-300, 200, 300, 200) turtle.done()
康托三分集的遞歸算法很直觀。
2.3 謝爾賓斯基三角形
謝爾賓斯基三角形(英語:Sierpinski triangle)由波蘭數(shù)學家謝爾賓斯基在1915年提出。
構造過程:
- 取一個實心的三角形(最好是等邊三角形)。
- 沿三邊中點的連線,將它分成四個小三角形。
- 去掉中間的那一個小三角形。
- 對其余三個小三角形重復上述過程直到條件不成立。
編碼實現(xiàn): 謝爾賓斯基三角形就是不停的畫三角形,在編碼之前約定三角形點之間的關系以及繪制方向如下圖所示。
import turtle import math turtle.speed(100) ''' 通過連接 3 個點的方式繪制三角形 pos是元組的元組((x1,y1),(x2,y2),(x3,y3)) def draw_triangle(pos): turtle.penup() # 移到第一個點 turtle.goto(pos[0]) turtle.pendown() # 連接 3 個點 for i in [1, 2, 0]: turtle.goto(pos[i]) # 計算三角形任意兩邊的中點坐標 def get_mid(p1, p2): return (p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2 繪制 謝爾賓斯基三角形 def sierpinski_triangle(*pos): # 用給定的點繪制三角形 draw_triangle(pos) p1, p2, p3 = pos # 計算三角形的邊長 side = math.fabs((p3[0] - p1[0]) / 2) # 如果邊長滿足條件,繼續(xù)繪制其它三角形 if side > 10: # p1和p2線段 的中心點 p1_p2_center_x, p1_p2_center_y = get_mid(p1, p2) # p2和p3線段 的中心點 p2_p3_center_x, p2_p3_center_y = get_mid(p2, p3) # p1和p3線段 的中心點 p1_p3_center_x, p1_p3_center_y = get_mid(p1, p3) # 繪制左下角三角形 sierpinski_triangle(p1, (p1_p2_center_x, p1_p2_center_y), (p1_p3_center_x, p1_p3_center_y)) # 繪制上邊三角形 sierpinski_triangle((p1_p2_center_x, p1_p2_center_y), p2, (p2_p3_center_x, p2_p3_center_y)) # 繪制右下角三角形 sierpinski_triangle((p1_p3_center_x, p1_p3_center_y), (p2_p3_center_x, p2_p3_center_y), p3) # 第一個點指左邊點,第二點指上面的點,第三個指右邊的點。 sierpinski_triangle((-200, -100), (0, 200), (200, -100)) turtle.done()
代碼執(zhí)行之后的結(jié)果:
用隨機的方法(Chaos Game),繪制謝爾賓斯基三角形:
構造過程:
任意取平面上三點 A,B,C,組成一個三角形。
在三角形 ABC 內(nèi)任意取一點 P,并畫出該點。
找出 P 和三角形其中一個頂點的中點,并畫出來。
把剛才找出來的中心點和三角形的任一頂點相連接,同樣取其中點,并畫出來。
重復上述流程,不停的獲取中心點。
注意,是畫點,上面的線段是為了直觀理解中心點位置。
編碼實現(xiàn):
import turtle import random turtle.speed(100) turtle.bgcolor('black') colors = ['red', 'green', 'blue', 'orange', 'yellow'] # 畫等邊三角形 def draw_triangle(pos): turtle.penup() turtle.goto(pos[0]) turtle.pendown() for i in [1, 2, 0]: turtle.goto(pos[i]) def sierpinski_triangle(*pos): # 畫三角形 draw_triangle(pos) p1, p2, p3 = pos # 在三角形中任取一點 ran_x, ran_y = (p1[0] + p3[0]) / 2, (p2[1] + p3[1]) / 2 for i in range(10000): # 畫點 turtle.penup() turtle.goto(ran_x, ran_y) turtle.pendown() turtle.dot(3, colors[i % 5]) # 隨機選擇 3 個頂點的一個頂點 ran_i = random.randint(0, 2) ding_p = pos[ran_i] # 計算任意點和頂點的中心點 ran_x, ran_y = (ran_x + ding_p[0]) / 2, (ran_y + ding_p[1]) / 2 sierpinski_triangle((-200, -100), (0, 200), (200, -100)) turtle.done()
隨機法是一個神奇的存在,當點數(shù)量很少時,看不出到底在畫什么。當點的數(shù)量增加后,如成千上萬后,會看到謝爾賓斯基三角形躍然于畫布上,不得不佩服數(shù)學家們天才般的大腦。
下圖是點數(shù)量為 10000 時的謝爾賓斯基三角形,是不是很震撼。
2.4 分形樹
繪制分形樹對于遞歸調(diào)用過程的理解有很大的幫助,其實前面所聊到的遞歸算法都是樹形遞進。分形樹能很形象的描述樹形遞歸的過程。
分形樹的算法實現(xiàn):
import turtle def draw_tree(size): if size >= 20: turtle.forward(size) # 1 # 畫右邊樹 turtle.right(20) draw_tree(size - 40) # 2 # 畫左邊樹 turtle.left(40) draw_tree(size - 40) # 后退 turtle.right(20) turtle.backward(size) turtle.left(90) draw_tree(80) turtle.done()
為了理解分形樹的遞歸過程,如上代碼可以先僅畫一個樹干兩個樹丫。
下面以圖示方式顯示左右兩邊的樹丫繪制過程。
3. 總結(jié)
分形幾何是大自然對數(shù)學的饋贈,當然這離不開數(shù)學家們的發(fā)現(xiàn)與研究,通過計算機科學對分形幾何的模擬,可以以可視化的方式更直觀地研究分形幾何學。這也是計算機科學對于各學科的巨大貢獻。
到此這篇關于Python 分形算法代碼詳解的文章就介紹到這了,更多相關Python 分形算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
python shapely.geometry.polygon任意兩個四邊形的IOU計算實例
這篇文章主要介紹了python shapely.geometry.polygon任意兩個四邊形的IOU計算實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04Pandas DataFrame實現(xiàn)任意位置插入一列或一行
Pandas是Python中最流行的數(shù)據(jù)處理和分析庫之一,在數(shù)據(jù)分析過程中,有時候需要在Dataframe中插入新的數(shù)據(jù)列,本文主要介紹了Pandas DataFrame實現(xiàn)任意位置插入一列或一行,具有一定的參考價值,感興趣的可以了解一下2023-08-08使用TensorBoard進行超參數(shù)優(yōu)化的實現(xiàn)
這篇文章主要介紹了使用TensorBoard進行超參數(shù)優(yōu)化的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-07-07python讀取word 中指定位置的表格及表格數(shù)據(jù)
這篇文章主要介紹了python讀取word 中指定位置的表格及表格數(shù)據(jù),本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友參考下吧2019-10-10