分形/阿波羅尼奧斯分形
- 阿波羅尼奧斯墊片 = 曲線型謝爾賓斯基墊片 = 萊布尼茨填充 = 阿波羅尼奧斯填充
- 階段 = 層級 = 步
- 內切圓 = 內接圓 = 3 個圓內的圓 = 內圓
- 間隙 = 曲線型三角形 = 理想三角形(因為邊在每個頂點處相切,它們之間的角度為零)= 3 個相切圓之間的區域

阿波羅尼奧斯墊片可以使用以下算法制作:[3]
所有演算法在 n 個階段後給出狀態。它是一個無限多個階段(圓圈)的極限集的近似值。


(待辦事項)

它將透過具有初始配置的示例墊片進行解釋:3 個具有整數曲率的內圓
該演算法使用
- 由中心 和曲率 定義的先前圓
- 圓的笛卡爾定理來計算下一個圓的曲率
- 復圓的笛卡爾定理來計算下一個圓的中心
當外圓圓心位於原點時,需要在圓心情況下選擇解。當整個墊片位於笛卡爾平面第一象限時,更容易。然後所有圓心都有正部分(實部和虛部)。
注意,變數 可以是曲率 或 因此 可用於計算曲率和圓心
使用列表 更容易定義圓。它包含兩個元素:圓心 和曲率
現在可以定義新的函式(Maxima CAS 程式碼)來計算與給定的 3 個圓相切的第 4 個圓。
f_pp(ck1,ck2,ck3):=block ([c4,k4,ck4], k4:f_p(ck1[2],ck2[2],ck3[2]), c4:f_p(ck1[1]*ck1[2],ck2[1]*ck2[2],ck3[1]*ck3[2])/k4, ck4:[c4,k4])$
f_pm(ck1,ck2,ck3):=block ([c4,k4,ck4], k4:f_p(ck1[2],ck2[2],ck3[2]), c4:f_m(ck1[1]*ck1[2],ck2[1]*ck2[2],ck3[1]*ck3[2])/k4, ck4:[c4,k4]);
f_mm(ck1,ck2,ck3):=block ([c4,k4,ck4], k4:f_m(ck1[2],ck2[2],ck3[2]), c4:f_m(ck1[1]*ck1[2],ck2[1]*ck2[2],ck3[1]*ck3[2])/k4, ck4:[c4,k4]);
f_mp_ck4(ck1,ck2,ck3):=block ([c4,k4], k4:solve_m_eq(ck1[2],ck2[2],ck3[2]), c4:solve_p_eq(ck1[1]*ck1[2],ck2[1]*ck2[2],ck3[1]*ck3[2])/k4, return([c4,k4]) );
函式 使用 函式來計算圓心和曲率。它用於計算幾乎所有沒有外圓的圓和硬圓。
函式 使用 函式來計算曲率和 函式來計算圓心。它用於計算硬圓。
函式 使用 函式來計算圓心和曲率。它用於計算外圓。
用於填充間隙的函式
[edit | edit source]fill_easy(ckla,cklb,cklc,max_stage):=block ([ckm], if max_step>0 then ( /* circle in the middle */ ckm:give_pp_ck4(ckla,cklb,cklc), /* 3 circles around */ fill_easy(ckla,cklb,ckm,max_stage-1), fill_easy(cklb,cklc,ckm,max_stage-1), fill_easy(ckla,cklc,ckm,max_stage-1)))$
fill_hard(ck_ic,ck_ia,ck_0out,max_stage):=block ([ck_1c,ck_2cc,ck_3ccc,ck_4ccca,ck_5cccac], /* hard circles */ if max_stage>0 then ( /* step 1 = circle in the middle */ ck_1c:f_pm(ck_ia,ck_ic,ck_0out), /* 1c */ /* step 2 = 3 circles around */ fill_easy(ck_ia,ck_0out,ck_1c,max_stage-1), /* 2ca */ fill_easy(ck_ia,ck_ic,ck_1c,max_stage-1), /* 2cb */ /* hard subgap 2cc */ if max_stage>1 then ck_2cc:f_pm(ck_ic,ck_1c,ck_0out), /* 2cc */ /* step 3 for subgap 2cc */ fill_easy(ck_0out,ck_1c,ck_2cc,max_stage-2), /* 3cca */ fill_easy(ck_ic,ck_1c,ck_2cc,max_stage-2), /* 3ccb */ if max_stage>2 then ck_3ccc:f_pm(ck_ic,ck_0out,ck_2cc), /* 3ccc */ /* step 4 for subgap 3ccc */ if max_stage>3 then ck_4ccca:f_pm(ck_0out,ck_2cc,ck_3ccc), fill_easy(ck_ic,ck_2cc,ck_3ccc,max_stage-3), /* 4cccb */ fill_easy(ck_ic,ck_0out,ck_3ccc,max_stage-3), /* 4cccc */ /* step 5 for subgap 4ccca */ fill_easy(ck_0out,ck_2cc,ck_4ccca,max_stage-4), /* 5cccaa */ fill_easy(ck_2cc,ck_3ccc,ck_4ccca,max_stage-4), /* 5cccab */ if max_stage>4 then ck_5cccac:f_pm(ck_0out,ck_3ccc,ck_4ccca)))$
構造
[edit | edit source]
- 初始階段:3 個相互相切的圓 =
- 零階段:2 個與前一個圓相切的圓:外圓 和內圓 ,其中:
- 第一階段:在之前的圓之間有 6 個空隙(= 曲線三角形)。三個空隙在圓周上(靠近外圓),三個空隙在中間(靠近內圓)。在每個空隙中放一個圓。
每個放在空隙中的新圓都會形成三個新的空隙(三叉)。
- 第二階段:有 18(6*3)個新的空隙。使用 函式在每個空隙中放置一個圓,除了一個硬圓。
- 後續階段:在每個階段的每個空隙中放置一個圓。在每個階段,只有一個硬圓,它在 空隙中。
由於所有圓都內切於外圓,因此從外圓開始更容易。
- 選擇二次影像的大小
- 計算外圓的半徑
- 將外圓放置在笛卡爾平面的第一象限
- 計算 3 個相等的初始圓的半徑[10]
- 找到初始圓的圓心。例如,將一個圓 放在上排,兩個圓 ( 和 ) 放在下排。
然後這些圓的圓心是等邊三角形的頂點,三角形邊長 因此
- 計算內圓
- "現在我們有一個可以開始的配置"[11] 有 6 個空隙要填補。5 個空隙很容易填補,而一個空隙 很難填補。
圓之間的關係
[edit | edit source]- 第 n 階段新圓圈數量 =
- n 階段後圓圈總數 =
其中
例如
- 階段 -1 = 初始配置(3 個內圓)
- 階段 0 給出 2 個新圓(一個外圓和一個最內圓)。所有圓圈 = 5
- 階段 1 給出 6 個新圓(所有圓圈 = 11)
- 階段 2 給出 18 個新圓(所有圓圈 = 29)
- 階段 3 給出 54 個新圓(所有圓圈 = 83)
- 階段 4 給出 162 個新圓(所有圓圈 = 245)
- 階段 5 給出 486 個新圓(所有圓圈 = 731)
- 階段 6 給出 1 458 個新圓(所有圓圈 = 2 189)
- 階段 7 給出 4 374 個新圓(所有圓圈 = 6 563)
- 階段 8 給出 13 122 個新圓(所有圓圈 = 19 685)
- 階段 9 給出 39 366 個新圓(所有圓圈 = 59 051)
- 階段 10 給出 118 098 個新圓(所有圓圈 = 177 149)
- 階段 11 給出 354 294 個新圓(所有圓圈 = 531 443)
- 階段 12 給出 1 062 882 個新圓(所有圓圈 = 1 594 325)
- 階段 13 給出 3 188 646 個新圓(所有圓圈 = 4 782 971)
- 階段 14 給出 9 565 938 個新圓(所有圓圈 = 14 348 909)
- 階段 15 給出 28 697 814 個新圓(所有圓圈 = 43 046 723)
- 階段 16 給出 86 093 442 個新圓(所有圓圈 = 129 140 165)
- 階段 17 給出 258 280 326 個新圓(所有圓圈 = 387 420 491)
- 階段 18 給出 774 840 978 個新圓(所有圓圈 = 1 162 261 469)
- 階段 19 給出 2 324 522 934 個新圓(所有圓圈 = 3 486 784 403)
- 階段 20 給出 6 973 568 802 個新圓(所有圓圈 = 10 460 353 205)
可以使用 Maxima CAS 程式碼計算
NumberOfStageCircles(stage):=
if stage =-1 then 3
elseif stage=0 then 2
else 2*3^stage;
NumberOfAllCircles(stage_max):=sum(NumberOfStageCircles(i),i,-1,stage_max);
for i:-1 step 1 thru 20 do print("stage ",i," gives ",NumberOfStageCircles(i)," new circles ( all circles = ",NumberOfAllCircles(i), " )");
圓圈數量快速增長,導致大檔案尺寸問題。可以
- 僅使用最多 5-7 階段。這似乎足以在短時間內生成良好的影像。[12]
- 不要繪製太小的圓圈(半徑小於畫素尺寸)[13]
- 將 svg 檔案轉換為 png(例如使用 Image Magic : "convert a.svg a.png")。然後,階段 12 svg 影像為 128 MB,而 png 檔案僅為 57 KB。
- 高興的是你得到了如此詳細的影像,並等待很長時間載入檔案,或者看看系統如何掛起(:-))
注意,只有一個曲率是用 函式計算的。
它是 。它也是唯一的負曲率。
所有其他曲率都是用 函式計算的。
| 階段 | 曲率 |
|---|---|
| -1 | |
| 0 | |
| 1 | |
| 2 |
Ken Stephenson 編寫的 CirclePack 程式
程式在上面解釋過,原始碼在 Apollonian_rc_6.svg 的描述中。
要執行,請將 apollonian.lisp 檔案放到您的主目錄和 Emacs/slime 中。要進行下一步更改,請更改 *max-step*
載入檔案以執行程式碼(批處理模式)
(load "apollonian.lisp")
; first run
;(require :asdf)
;(require :asdf-install)
;(asdf-install:install :zpng)
;(asdf-install:install :Vecto)
; you must press 2 and 0 when the program asks
; next times load packages from disk
(asdf:operate 'asdf:load-op 'vecto)
(in-package vecto)
;-----------------------------------------------------------------------
;---------------------------- definitions of functions ---------------
;-----------------------------------------------------------------------
; kc is a list describing circle (list k c) where k is curvature and c is a center ( complex number)
; k can be positive ( inner circle) , negative ( outer circle) or zero ( = line )
(defun draw-vecto-circle (kc)
(let* ((c (second kc))
(r (abs (/ 1 (first kc))))) ; r = abs(1/k)
(centered-circle-path (realpart c) (imagpart c) r))) ; vecto
; Desfirsttes' circle theorem
(defun solve-equation-m (k1 k2 k3)
(- (+ k1 k2 k3 ) (* 2 (sqrt (+ (* k1 k2) (* k2 k3) (* k1 k3))))))
(defun solve-equation-p (k1 k2 k3)
(+ (+ k1 k2 k3 ) (* 2 (sqrt (+ (* k1 k2) (* k2 k3) (* k1 k3))))))
; compute, draws and gives back 4-th circle usind solve-equation-p and solve-equation-p
(defun draw-forth-circle-pp (kc1 kc2 kc3)
(let* ((k1 (first kc1))
(k2 (first kc2))
(k3 (first kc3))
(p1 (* k1 (second kc1))) ; pn = kn * cn
(p2 (* k2 (second kc2)))
(p3 (* k3 (second kc3)))
(k4 (solve-equation-p k1 k2 k3)) ; find k
(c4 (/ (solve-equation-p p1 p2 p3) k4)) ; find c
(kc4 (list k4 c4)))
(draw-vecto-circle kc4) ; draw
kc4)) ; return 4-th circle
; compute, draws and gives back 4-th circle usind solve-equation-p and solve-equation-m
(defun draw-forth-circle-pm (kc1 kc2 kc3)
(let* ((k1 (first kc1))
(k2 (first kc2))
(k3 (first kc3))
(p1 (* k1 (second kc1)))
(p2 (* k2 (second kc2)))
(p3 (* k3 (second kc3)))
(k4 (solve-equation-p k1 k2 k3))
(c4 (/ (solve-equation-m p1 p2 p3) k4))
(kc4 (list k4 c4)))
(draw-vecto-circle kc4)
kc4))
; easy = pp
(defun fill-easy-gap (kc1 kc2 kc3 steps)
(when (> steps 0)
(let* ((kc4 (draw-forth-circle-pp kc1 kc2 kc3))) ; 4-th circle
(fill-easy-gap kc1 kc2 kc4 (- steps 1)) ; 3 subgaps
(fill-easy-gap kc2 kc3 kc4 (- steps 1))
(fill-easy-gap kc3 kc1 kc4 (- steps 1)))))
; only for gap 1c = hard gap
(defun fill-hard-gap (kc-ic kc-ia kc-0out steps)
(let* (kc-1c kc-2cc kc-3ccc kc-4ccca kc-5cccac) ; hard circles , also kc-6cccacc
;------------ gap 1c --------------------------------------------
(when (> steps 0) (setq kc-1c (draw-forth-circle-pm kc-ic kc-ia kc-0out)) ; kc-1c hard
(fill-easy-gap kc-ia kc-0out kc-1c (- steps 1)) ; kc-2ca
(fill-easy-gap kc-ia kc-ic kc-1c (- steps 1)) ; kc-2cb
; ----------- hard subgap 2cc ------------------------------------
(when (> steps 1) (setq kc-2cc (draw-forth-circle-pm kc-ic kc-0out kc-1c)) ; kc-2cc hard
(fill-easy-gap kc-0out kc-1c kc-2cc (- steps 2)) ; kc-3cca
(fill-easy-gap kc-ic kc-1c kc-2cc (- steps 2)) ; kc-3ccb
; ----------- hard subgap 3ccc ------------------------------------
(when (> steps 2) (setq kc-3ccc (draw-forth-circle-pm kc-ic kc-0out kc-2cc)) ; kc-3ccc hard
(fill-easy-gap kc-ic kc-2cc kc-3ccc (- steps 3)) ; kc-4cccb
(fill-easy-gap kc-ic kc-0out kc-3ccc (- steps 3)) ; kc-4cccc
; ----------- hard subgap 4ccca ------------------------------------
(when (> steps 3) (setq kc-4ccca (draw-forth-circle-pm kc-0out kc-2cc kc-3ccc)) ; kc-4ccca hard
(fill-easy-gap kc-0out kc-2cc kc-4ccca (- steps 4)) ; kc-5cccaa
(fill-easy-gap kc-2cc kc-3ccc kc-4ccca (- steps 4)) ; kc-5cccab
(when (> steps 4) (setq kc-5cccac (draw-forth-circle-pm kc-0out kc-3ccc kc-4ccca))))))))) ; kc-5cccac hard
; example of use : (draw-apollonian-gasket "a.png" 800 2)
; classical Desfirsttes configuration : 3 mutually tangent circles and 4-th inside ( and fith outside)
(defun draw-apollonian-gasket-n3 (file side step)
(with-canvas (:width side :height side) ; vecto
(set-rgb-stroke 0 0 0) ; vecto
(set-line-width 1) ; vecto
(let* ( (r0out (/ side 2))
(k0out (- (/ 1 r0out)))
(c0out (complex r0out r0out))
(kc0out (list k0out c0out)) ; list defining circle
; a1:float(1 + 2 / sqrt(3)), http://www2.stetson.edu/~efriedma/cirincir/
(a (+ 1 (/ 2 (sqrt 3))))
(ri (/ r0out a)) ; three equal inner circles = initial circles
(ki (/ 1 ri))
(cia (complex r0out (- side ri))) ; one circle in upper row
(kcia (list ki cia))
(h (* ri (sqrt 3))) ; height of equilateral triangle with side = 2*ri
; 2 circles in lower row
(cib (complex (+ r0out ri) (- side (+ h ri))))
(cic (complex (- r0out ri) (- side (+ h ri))))
(kcib (list ki cib))
(kcic (list ki cic))
kc0in )
; drawing code
; step -1 = three equal inner circles
(draw-vecto-circle kcia ) ; ia
(draw-vecto-circle kcib ) ; ib
(draw-vecto-circle kcic ) ; ic
; step 0 = outer and most inner circle
(draw-vecto-circle kc0out ) ; 0out
(setq kc0in ( draw-forth-circle-pp kcia kcib kcic )) ; 0in
; this is starting configuration.
; One can go to the next steps now
; Fill 6 gaps :
; 3 peripheral gaps
(fill-easy-gap kcia kcib kc0out step) ; 1a
(fill-easy-gap kcib kcic kc0out step) ; 1b
(fill-hard-gap kcic kcia kc0out step) ; 1c
; 3 medial gaps
(fill-easy-gap kcia kcib kc0in step) ; 1d
(fill-easy-gap kcib kcic kc0in step) ; 1e
(fill-easy-gap kcic kcia kc0in step) ; 1f
; rest of drawing code
(stroke)) ; before save ( vecto procedure)
(print (save-png file)))) ; info text and vecto procedure
;---------------compile ---------------------------------
(compile 'draw-vecto-circle )
(compile 'solve-equation-m)
(compile 'solve-equation-p)
(compile 'draw-forth-circle-pp)
(compile 'draw-forth-circle-pm)
(compile 'fill-easy-gap)
(compile 'fill-hard-gap)
(compile 'draw-apollonian-gasket-n3)
;----------global var ----------------------
(defparameter *max-step* 0 " maximal step of drawing apollonian gasket from. It is an integer >= 0 ")
(defparameter *file-name*
(make-pathname
:name (concatenate 'string "apollonian-n3-s" (write-to-string *max-step*))
:type "png")
"name (or pathname) of png file ")
;====================================== run ==================================
(draw-apollonian-gasket-n3 *file-name* 800 *max-step*)

這是一個增量演算法,它維護著一個包含三個相互接觸的圓的佇列。主迴圈從佇列的開頭開始,移除一個三元組,用所需的圓形填充它,將生成的圓形新增到一個用於繪製為 SVG 的圓形列表中,並將新增圓形後產生的三個三元組新增到計算佇列的末尾。作為額外功能,這些圓形被著色,因此沒有兩個相鄰的圓形具有相同的顏色。
用法:將兩個 SVG 模板部分和中間的 Javascript 部分合併到一個 SVG 檔案中,並載入到網頁瀏覽器(或另一個支援 Javascript 或 ECMAScript 的 SVG 瀏覽器)中。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100%" height="100%" viewBox="0 0 768 768"
onload="init(evt)"
><title>Apollonian Fractal</title
><desc>Randomized Apollonian fractal circle packing</desc
><script type="text/ecmascript"><![CDATA[
// SVG properties
var ns = "http://www.w3.org/2000/svg";
var xns = "http://www.w3.org/1999/xlink";
var SVGDocument = null;
var size = 768; // should match 'viewBox'
var minsize = 0.001;
// convert internal coordinates and lengths to SVG
function coord(x) { return x*size/2 + size/2; }
function dist(d) { return d*size/2; }
// complex numbers
function C(r,i) { this.r = r; this.i = i; }
function Cconj(c) { return new C(c.r, -c.i); }
function Cadd(c,d) { return new C(c.r+d.r,c.i+d.i); }
function Csub(c,d) { return new C(c.r-d.r,c.i-d.i); }
function Cmul(c,d) { return new C(c.r*d.r-c.i*d.i,c.r*d.i+c.i*d.r); }
function Csqrt(c) { return new C(Math.sqrt(Math.sqrt(c.r*c.r+c.i*c.i)) * Math.cos(Math.atan2(c.i,c.r)/2),
Math.sqrt(Math.sqrt(c.r*c.r+c.i*c.i)) * Math.sin(Math.atan2(c.i,c.r)/2)); }
// sort points into order
function clockwise(a, b, c) {
var x1 = a.x-b.x; var y1 = a.y-b.y;
var x2 = c.x-b.x; var y2 = c.y-b.y;
if ((x1*y2-y1*x2) >= 0) return [a,b,c]; else return [a,c,b];
}
// compute the 4th circle touching 3 circles, each of which touch the other two
function Kiss(a, b, c, initial) {
var k1 = 1 / a.r; var z1 = new C(a.x, a.y); var kz1 = Cmul(new C(k1,0),z1);
var k2 = 1 / b.r; var z2 = new C(b.x, b.y); var kz2 = Cmul(new C(k2,0),z2);
var k3 = 1 / c.r; var z3 = new C(c.x, c.y); var kz3 = Cmul(new C(k3,0),z3);
var k4p = k1 + k2 + k3 + 2*Math.sqrt(k1*k2 + k2*k3 + k3*k1);
var k4m = k1 + k2 + k3 - 2*Math.sqrt(k1*k2 + k2*k3 + k3*k1);
var kz4p = Cadd(Cadd(Cadd(kz1,kz2),kz3),Cmul(new C(2,0),
Csqrt(Cadd(Cadd(Cmul(kz1,kz2),Cmul(kz2,kz3)),Cmul(kz3,kz1)))));
var kz4m = Csub(Cadd(Cadd(kz1,kz2),kz3),Cmul(new C(2,0),
Csqrt(Cadd(Cadd(Cmul(kz1,kz2),Cmul(kz2,kz3)),Cmul(kz3,kz1)))));
var k4;
var kz4;
var k4b;
var kz4b;
var cs = new Array();
if (k4p > k4m) { k4 = k4p; kz4 = kz4p; k4b = k4m; kz4b = kz4m; }
else { k4 = k4m; kz4 = kz4m; k4b = k4p; kz4b = kz4p; }
var cc = new Circle(kz4.r/k4,kz4.i/k4,Math.abs(1/k4), 6 - a.colour - b.colour - c.colour);
var dx = a.x - cc.x
var dy = a.y - cc.y
var dr = a.r + cc.r
if (Math.abs(dx * dx + dy *dy - dr * dr) > 0.0001) {
cc = new Circle(kz4b.r/k4,kz4b.i/k4,Math.abs(1/k4), 6 - a.colour - b.colour - c.colour);
}
cs[cs.length] = cc;
if (initial) {
cc = new Circle(kz4b.r/k4b,kz4b.i/k4b,Math.abs(1/k4b), 6 - a.colour - b.colour - c.colour);
cs[cs.length] = cc;
}
return cs;
}
// called once on load
function init(evt) {
// get document
SVGDocument = evt.target.ownerDocument;
// initial bounding circle
var b = new Circle(0, 0, -1, 0);
// insert two randomly positioned touching circles
var tr = 1-Math.random()/2;
var pa = Math.PI/2 - Math.asin(Math.random()*(1-tr)/tr);
var px = tr * Math.cos(pa);
var py = tr * Math.sin(pa);
var pr = 1 - tr;
var qr = (1 - pr) * (1 - Math.cos(pa + Math.PI/2))
/ (1 + pr - (1 - pr) * Math.cos(pa + Math.PI/2));
var qx = 0;
var qy = qr - 1;
var p = new Circle(px, py, pr, 1);
var q = new Circle(qx, qy, qr, 2);
// a queue to contain triples of touching circles
var queue = new Array();
var cs = Kiss(b,p,q, true);
queue[queue.length] = [b,p,cs[0]];
queue[queue.length] = [b,cs[0],q];
queue[queue.length] = [cs[0],p,q];
queue[queue.length] = [b,p,cs[1]];
queue[queue.length] = [b,cs[1],q];
queue[queue.length] = [cs[1],p,q];
// a queue to contain circles to draw
var draw = new Array();
draw[draw.length] = b;
draw[draw.length] = p;
draw[draw.length] = q;
draw[draw.length] = cs[0];
draw[draw.length] = cs[1];
// add 10000 more circles to the draw queue
// adding new triples to the compute queue
var c;
for (c = 0; c < Math.min(queue.length, 10000); c = c + 1) {
var c0 = queue[c][0];
var c1 = queue[c][1];
var c2 = queue[c][2];
var ncs = Kiss(c0,c1,c2);
var nc = ncs[0];
if (nc.r > minsize) {
queue[queue.length] = [nc,c1,c2];
queue[queue.length] = [c0,nc,c2];
queue[queue.length] = [c0,c1,nc];
draw[draw.length] = nc;
}
}
// add all generated circles to an SVG <g> element
var g = SVGDocument.createElementNS(ns, "g");
g.setAttributeNS(null, "stroke", "black");
g.setAttributeNS(null, "stroke-width", "1");
var i;
for (i = 0; i < draw.length; i = i + 1) {
g.appendChild(draw[i].draw());
}
// link the <g>s into the DOM so they are displayed
var svg = SVGDocument.documentElement;
svg.appendChild(g);
} // init()
// circle class
function Circle(x, y, r, colour) {
// properties of a circle
this.x = x;
this.y = y;
this.r = r;
this.colour = colour;
// convert to svg
this.draw = function() {
var colours = ["white", "red", "yellow", "cyan"];
var c = SVGDocument.createElementNS(ns, "circle");
c.setAttributeNS(null, "fill", colours[this.colour]);
c.setAttributeNS(null, "cx", coord(this.x));
c.setAttributeNS(null, "cy", coord(this.y));
c.setAttributeNS(null, "r", dist(this.r));
return c;
};
} // Circle()
]]></script></svg>
- ↑ 阿波羅尼墊片
- ↑ mathforum : 阿波羅尼問題
- ↑ 阿波羅尼的切線問題 在 MathPages 上
- ↑ 曼德爾布羅特演算法 在耶魯大學的《分形幾何學》中,作者邁克爾·弗雷姆、貝努瓦·曼德爾布羅特和尼爾·奈格爾
- ↑ 使用 n 個相同圓形繪製二維阿波羅尼墊片 在 Matlab 中,作者 Guillaume JACQUENOT
- ↑ 阿波羅尼墊片 在 Mathematica 和 Povray 中,作者 Paul Nylander
- ↑ 繪製阿波羅尼墊片 使用 Common Lisp 和 Vecto,作者 Luis Diego Fallas
- ↑ 萊布尼茨填充 作者 Takaya Iwamoto,使用 AutoLisp 編寫的程式
- ↑ 阿波羅尼墊片 - 作者 Paul Bourke 使用 BAsic 和 C 編寫
- ↑ 如何在單位圓內填充 n 個圓形 作者 Erich Friedman
- ↑ SVG 數學動畫示例:阿波羅尼墊片 (-15,32,32,33) 作者 KiHyuck Hong。檢視原始碼。
- ↑ SVG 數學動畫示例:阿波羅尼墊片 (-15,32,32,33) 作者 KiHyuck Hong
- ↑ 檔案阿波羅尼墊片 包含大約 8140 個圓形,但看起來像是由大約 20 步生成的。因此它應該大約有 10 460 353 205 個圓形
- ↑ 阿波羅尼墊片在 Haskell 和 Diagrams 中 作者 Brent Yorgey
- ↑ Apollonian.hs - haskell 程式碼