跳轉到內容

分形/曼德勃羅圖形

來自華夏公益教科書

部分

  • 克勞德·海蘭德-艾倫為基於 CPU 的曼德勃羅集視覺化設計的庫和 c 程式[1]
  • 用於 Haskell 的 mandelbrot-prelude 庫(終端中低解析度影像,使用塊圖形字元)

依賴項

[編輯 | 編輯原始碼]

共享庫

[編輯 | 編輯原始碼]
ldd m-render
	linux-vdso.so.1 =>  (0x00007ffcae4e7000)
	libmandelbrot-graphics.so => /home/a/opt/lib/libmandelbrot-graphics.so (0x00007fb8f9a12000)
	libcairo.so.2 => /usr/lib/x86_64-linux-gnu/libcairo.so.2 (0x00007fb8f96df000)
	libmandelbrot-numerics.so => /home/a/opt/lib/libmandelbrot-numerics.so (0x00007fb8f94cf000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fb8f92b2000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb8f8ee9000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fb8f8bdf000)
	libgomp.so.1 => /usr/lib/x86_64-linux-gnu/libgomp.so.1 (0x00007fb8f89bd000)
	libpixman-1.so.0 => /usr/lib/x86_64-linux-gnu/libpixman-1.so.0 (0x00007fb8f8715000)
	libfontconfig.so.1 => /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 (0x00007fb8f84d1000)
	libfreetype.so.6 => /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007fb8f8227000)
	libpng12.so.0 => /lib/x86_64-linux-gnu/libpng12.so.0 (0x00007fb8f8002000)
	libxcb-shm.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-shm.so.0 (0x00007fb8f7dfd000)
	libxcb-render.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-render.so.0 (0x00007fb8f7bf3000)
	libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007fb8f79d1000)
	libXrender.so.1 => /usr/lib/x86_64-linux-gnu/libXrender.so.1 (0x00007fb8f77c6000)
	libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007fb8f748c000)
	libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007fb8f727a000)
	libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fb8f705f000)
	librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fb8f6e57000)
	libmpc.so.3 => /usr/local/lib/libmpc.so.3 (0x00007fb8f6c3e000)
	libmpfr.so.4 => /usr/local/lib/libmpfr.so.4 (0x00007fb8f69db000)
	libgmp.so.10 => /usr/local/lib/libgmp.so.10 (0x00007fb8f6764000)
	/lib64/ld-linux-x86-64.so.2 (0x0000564eca780000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fb8f6560000)
	libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007fb8f6336000)
	libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007fb8f6132000)
	libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007fb8f5f2b000)
objdump -p m-render | grep NEEDED
  NEEDED               libmandelbrot-graphics.so
  NEEDED               libcairo.so.2
  NEEDED               libmandelbrot-numerics.so
  NEEDED               libpthread.so.0
  NEEDED               libc.so.6
objdump -p m-stretching-cusps | grep NEEDED
  NEEDED               libmandelbrot-graphics.so
  NEEDED               libcairo.so.2
  NEEDED               libmandelbrot-numerics.so
  NEEDED               libm.so.6
  NEEDED               libgmp.so.10
  NEEDED               libpthread.so.0
  NEEDED               libc.so.6
git clone https://code.mathr.co.uk/mandelbrot-graphics.git

以及包含 mandelbrot-graphics 的目錄中

 make -C mandelbrot-graphics/c/lib prefix=${HOME}/opt install
 make -C mandelbrot-graphics/c/bin prefix=${HOME}/opt install

然後執行

 export LD_LIBRARY_PATH=${HOME}/opt/lib

檢查

echo $LD_LIBRARY_PATH

結果

 /home/a/opt/lib

或者

 export PATH=${HOME}/opt/bin:${PATH}

檢查

    echo $PATH

要永久設定它,更改檔案

  • .profile[2]
  • /etc/ld.so.conf.d/*.conf[3]

從 mandelbrot-graphics 目錄中開啟的控制檯中

 git pull

如果你進行了一些本地更改,你可以撤銷它們

 git checkout -f

然後

 git pull

現在重新安裝

重新編譯新版本

[編輯 | 編輯原始碼]

bash 指令碼

#!/bin/bash
cd ~
make -C mandelbrot-graphics/c/lib prefix=${HOME}/opt install
make -C mandelbrot-graphics/c/bin prefix=${HOME}/opt install
export LD_LIBRARY_PATH=${HOME}/opt/lib 
export PATH=${HOME}/opt/bin:${PATH}
cd /home/a/mandelbrot-graphics/c/bin

字首 m 來自 Mandelbrot

名稱中的字首 r 或 d 描述精度

  • d = 雙精度
  • r = 任意精度

示例

 m_d_attractor(double _Complex *z_out, double _Complex z_guess, double _Complex c, int period, int maxsteps)
 m_r_attractor(mpc_t z_out, const mpc_t z_guess, const mpc_t c, int period, int maxsteps)

如何使用它?

[編輯 | 編輯原始碼]

Haskell 程式

let c = nucleus 100 . (!! (8 * 2 * 100)) . exRayIn 8 . fromQ . fst . addressAngles . pAddress $ "1 7/12 5/9 100" ; r = 2 * magnitude (size 100 c) in putImage c r 10000

它提供

  • 終端中低解析度影像,使用塊圖形字元
  • 中心、大小和迭代次數
-0.5664388911664133 + -0.4792791697756855 i @ 2.810e-8 (10000 iterations)

lib 目錄中的過程

[編輯 | 編輯原始碼]
  • C 原始碼應該*只*包含 #include <mandelbrot-numerics.h>
  • 使用 pkg-config 編譯和連結:參見 mandelbrot-numerics/c/bin/Makefile 作為示例
  • 開始的最快方法是將你的檔案放在 mandelbrot-numerics/c/bin 中,然後執行 make


m_d_transform_rectangular

[編輯 | 編輯原始碼]
 m_d_transform *rect = m_d_transform_rectangular(w, h, c, r); //

其中

  • w = 寬度(以畫素為單位)
  • h = 高度(以畫素為單位)
  • c = 影像的中心(複數)
  • r = 影像的半徑(雙精度數)

m_d_interior

[編輯 | 編輯原始碼]

找到曼德勃羅集的點 c,給定特定的雙曲分量和所需的內部角度。它涉及在兩個復變數中使用牛頓法來解決[4]

其中

  • p 是目標分量的週期
  • 是所需的內部角度
  • r 是內部半徑 。當 r = 1.0 時,點在邊界上。當 r = 0 時,點位於分量中心(= 核心)
  • 是點 c 的乘數

雙曲線分量由以下描述

  • 週期
  • 核心

語法

 extern m_newton m_d_interior(double _Complex *z_out, double _Complex *c_out, double _Complex z_guess, double _Complex c_guess, double _Complex interior, int period, int maxsteps) 
 
 

輸入

  • z_guess
  • c_guess(通常是選定雙曲線分量的核心)
  • interior(乘數)
  • 週期
  • maxstep

輸出

  • c 是點的座標(c_out)
  • z 是週期點(z_out)
  • result(m_newton)描述牛頓演算法如何結束:m_failed、m_stepped、m_converged。它在 ~/mandelbrot-numerics/c/include/mandelbrot-numerics.h 中定義


使用示例

 m_d_interior(&z, &half, nucleus, nucleus, -1, period, 64);
 m_d_interior(&z, &cusp, nucleus, nucleus, 1, period, 64);
 m_d_interior(&z, &third2, -1, -1, cexp(I * twopi / 3), 2, 64);

bin 目錄中的程式

[edit | edit source]

列表

~/mandelbrot-graphics/c/bin$ ls -1a *.c

結果

m-cardioid-warping.c   
m-render.c             
m-subwake-diagram-b.c
m-dense-misiurewicz.c  
m-stretching-cusps.c   
m-subwake-diagram-c.c
m-feigenbaum-zoom.c    
m-subwake-diagram-a.c

m-warped-midgets

[edit | edit source]
./m-warped-midgets

結果

     4 -1.565201668337550256e-01 + 1.032247108922831780e+00 i @ 1.697e-02
     8 4.048996651751222142e-01 + 1.458203637665893004e-01 i @ 2.743e-03
    16 2.925037532341934199e-01 + 1.492506899834379792e-02 i @ 3.484e-04
    32 2.602618199285007261e-01 + 1.667791320926505921e-03 i @ 4.113e-05
    64 2.524934589775105209e-01 + 1.971526796077277045e-04 i @ 4.920e-06
   128 2.506132008410751344e-01 + 2.396932642510365294e-05 i @ 5.997e-07
   256 2.501519680089798192e-01 + 2.954962325906873815e-06 i @ 7.398e-08
   512 2.500378219137852631e-01 + 3.668242052764783887e-07 i @ 9.185e-09
  1024 2.500094340031833728e-01 + 4.569478652064606379e-08 i @ 1.144e-09
  2048 2.500023558032561377e-01 + 5.701985912706822671e-09 i @ 1.428e-10
  4096 2.500005886128087162e-01 + 7.121326948562671441e-10 i @ 1.783e-11
  8192 2.500001471109009610e-01 + 8.897814201389663379e-11 i @ 2.228e-12


週期性掃描

[edit | edit source]

週期性掃描[5]:用曼德布羅集分量的週期標記引數平面的圖片可以提供對其更深層結構的洞察。


檔案:m-period.scan.c

執行控制檯程式

./m-period-scan

usage: ./m-period-scan out.png width height creal cimag radius maxiters mingridsize minfontsize maxfontsize maxatoms periodmod periodneq

示例

./m-period-scan out1.png 1500	1000 0.0	0.0 1.5  10000   100 	0.1	30.0     100  3 1

莫比烏斯

[edit | edit source]

莫比烏斯變換

./moebius
find point c of component with period = 2 	 multiplier = -0.4999999999999998+0.8660254037844387	 located near c=  -1.0000000000000000+0.0000000000000000
find point c of component with period = 4 	 multiplier = -1.0000000000000000+0.0000000000000000	 located near c=  -1.3107026413368328+0.0000000000000000
find point c of component with period = 4 	 multiplier = -0.4999999999999998+0.8660254037844387	 located near c=  -1.3107026413368328+0.0000000000000000
find point c of component with period = 8 	 multiplier = -1.0000000000000000+0.0000000000000000	 located near c=  -1.3815474844320617+0.0000000000000000
find point c of component with period = 8 	 multiplier = -0.4999999999999998+0.8660254037844387	 located near c=  -1.3815474844320617+0.0000000000000000
find point c of component with period = 2 	 multiplier = -0.5000000000000004-0.8660254037844384	 located near c=  -1.0000000000000000+0.0000000000000000
find point c of component with period = 2 	 multiplier = -0.8090169943749476-0.5877852522924730	 located near c=  -1.0000000000000000+0.0000000000000000
find point c of component with period = 2 	 multiplier = -0.7071067811865477-0.7071067811865475	 located near c=  -1.0000000000000000+0.0000000000000000
find point c of component with period = 2 	 multiplier = -0.6548607339452852-0.7557495743542582	 located near c=  -1.0000000000000000+0.0000000000000000
find point c of component with period = 3 	 multiplier = -1.0000000000000000+0.0000000000000000	 located near c=  -1.7548776662466927+0.0000000000000000
find point c of component with period = 3 	 multiplier = 1.0000000000000000+0.0000000000000000	 located near c=  -1.7548776662466927+0.0000000000000000
find point c of component with period = 6 	 multiplier = -1.0000000000000000+0.0000000000000000	 located near c=  -1.7728929033816239+0.0000000000000000
find point c of component with period = 6 	 multiplier = -0.4999999999999998+0.8660254037844387	 located near c=  -1.7728929033816239+0.0000000000000000
find point c of component with period = 12 	 multiplier = -1.0000000000000000+0.0000000000000000	 located near c=  -1.7782668211110817+0.0000000000000000
find point c of component with period = 12 	 multiplier = -0.4999999999999998+0.8660254037844387	 located near c=  -1.7782668211110817+0.0000000000000000

m-furcation-rainbow

[edit | edit source]
  For non-real C you can plot all the limit-cycle Z on one image, chances of overlap are small.  You can colour according to the position along the path.  
  In attached I have coloured using hue red at roots, going through yellow towards the next bond point in a straight line through the   interior coordinate space (interior coordinate is derivative of limit cycle).  
  I have just plotted points, so there are gaps.  Perhaps it could be improved by drawing line segments between Z values, but I'm not 100% sure if the first Z value found will always correspond to the same logical line, 
  and keeping track of a changing number of "previous Z" values isn't too fun either. Claude[6]


執行

 /m-furcation-rainbow 13.png  "1/3" "1/3" "1/3"

m-dense-misiurewicz

[edit | edit source]
圍繞主 Misiurewicz 點的週期從 2 到 1024 進行縮放

該程式基於 mandelbrot-graphics 中的 m-render.c。

它繪製一系列 png 影像


m-island-zoom

[edit | edit source]
m-island-zoom

製作 150 張 png 影像,顯示縮放至 3 個島嶼(尾流中最大的島嶼)

  • 一個位於主天線(週期 3)上,中心 c = -1.754877666246693 +0.000000000000000 i,位於 1/2 尾流中
  • 週期 4,中心 c = -0.156520166833755 +1.032247108922832 i,位於 1/3 尾流中
  • 週期 5,地址為 1-> 2-(1/3)-> 6,中心 c = -1.256367930068181 +0.380320963472722 i

心形變形

[edit | edit source]
曼德布羅集心形周圍的共形變形

曼德布羅集心形外部被變形以呈現旋轉的外觀。

變換由較小的元件組成,包括

  • 心形對映到圓
  • 圓到直線的莫比烏斯變換
  • 線性平移(動畫化)
  • 線性平移的逆
  • 圓到直線的莫比烏斯變換的逆

這些變換及其導數(用於距離估計著色)在此處描述:https://mathr.co.uk/blog/2013-12-16_stretching_cusps.html

用於渲染動畫的程式是在 C 中使用此處找到的 mandelbrot-graphics 庫實現的:https://code.mathr.co.uk/mandelbrot-graphics 該程式位於儲存庫中,為 c/bin/m-cardioid/warping.c https://code.mathr.co.uk/mandelbrot-graphics/blob/60adc5ab8f14aab1be479469dfcf5ad3469feea0:/c/bin/m-cardioid-warping.c

x 和內角之間有什麼關係?

毛髮

[edit | edit source]
在曼德布羅集中圍繞費根鮑姆點進行縮放,顯示毛髮

m-stretching-cusps

[edit | edit source]
曼德布羅集主心形的展開

可以新增使用說明

if (! (argc == 7)) {
    printf("no input \n");
    printf("example usage :  \n");
    printf("%s re(nucleus) im(nucleus) period t_zero t_one t_infinity  \n", argv[0] );
    printf("%s 0 0 1 1/2 1/3 0  \n", argv[0] );
    return 1;
  }


示例用法

 m-stretching-cusps 0 0 1 1/2 1/3 0

輸入

  • 父分量
    • re(核心)
    • im(核心)
    • 週期
  • 3 個子分量的內角
    • t0
    • t1
    • tinfinity


測試結果

 P0 = -7.5000000000000000e-01 1.2246467991473532e-16
 P1 = -1.2499999999999981e-01 6.4951905283832900e-01
 Pinf = 2.5000000000000000e-01 0.0000000000000000e+00

和影像 out.png


duble r = 0.5; // proportional to the number of components on the strip, 
 /*
  r = 0.5 gives 4 prominent components counted from period 1 to one side only 
  r = 1.0 gives 10 components
  r = 1.5 gives 15
  r = 2.0 gives 20 ( one can see 2 sides of cardioid ?? because it is near cusp)
  r = 2.5 gives 26
  r = 5.0 gives 50 



它使用


m-stretching-cusps 0 0 1 1/2 1/3 0
parent component with period = 1 and nucleus = 0.0000000000000000e+00 0.0000000000000000e+00
child component with with internal angle tzero = 1/2 and nucleus c = zero = -7.5000000000000000e-01 1.2246467991473532e-16  
child component with with internal angle tone = 1/3 and nucleus c = one = -1.2499999999999981e-01 6.4951905283832900e-01
child component with with internal angle tinfinity = 0 and nucleus c = infinity = 2.5000000000000000e-01 0.0000000000000000e+00
Moebius coefficients
	a = -0.5000000000000002 ; -0.8660254037844387
	b = 1.4999999999999998 ; -0.8660254037844390
	c = 0.5000000000000002 ; 0.8660254037844387
	d = 1.4999999999999998 ; -0.8660254037844388

image 1_0.500000.png saved
filename = period_r

m-misiurewicz-basins

[edit | edit source]
m-misiurewicz-basins
usage: m-misiurewicz-basins out.png width height creal cimag radius maxiters preperiod period


m-render

[edit | edit source]

它是其他程式的基礎程式。

這段程式碼片段描述瞭如何使用它

int main(int argc, char **argv) {
  if (argc != 8) {
    fprintf(stderr, "usage: %s out.png width height creal cimag radius maxiters\n", argv[0]);
    return 1;
  }

示例

  m-render a.png 1000 1000  -0.75  0 1.5 10000

結果是使用 DEM 的曼德布羅集邊界

曼德布羅集邊界


m-render 1995.png 7680 4320 -0.5664388911664133 -0.4792791697756855 3e-8 10000 1

m-streching-feigenbaum.c

[edit | edit source]

m-subwake-diagram-a

[編輯 | 編輯原始碼]
m-subwake-diagram-a

m-subwake-diagram-b

[編輯 | 編輯原始碼]
m-subwake-diagram-b

m-subwake-diagram-c

[編輯 | 編輯原始碼]
m-subwake-diagram-c

參考文獻

[編輯 | 編輯原始碼]
  1. mandelbrot-graphics - 由 Claude Heiland-Allen 編寫的基於 CPU 的 Mandelbrot 集視覺化程式
  2. stackoverflow 問題:如何在 Linux 上永久設定路徑
  3. ubuntu 環境變數
  4. Mandelbrot 集中的內部座標,作者:Claude Heiland-Allen
  5. 週期性掃描,作者:Claude Heiland-Allen
  6. fractalforums.org : 三叉分岔及更多
  7. 維基百科中關於莫比烏斯變換的顯式行列式公式
華夏公益教科書