第9章 9.1 畑政義写像とは 【リスト9-1】 畑政義写像によるコッホ曲線 from tkinter import * import math #■データ定義 DSP=[X0, Y0, SX, SY, width, height] # X0, Y0 : 表示開始位置 # SX, SY : XY方向スケール # Width, height : キャンバスの幅と高さ # CL : 描画カラーコード s36=math.sqrt(3)/6 A=complex(0.0, 0.0) B=complex(1/2, s36) C=complex(0.0, 0.0) D=complex(1/2, -s36) DSP=[20,160,300,300, 350, 200] CL=["#FF0000", "#FF0000"]; LOOP=14 #■共役複素数 def conj(Z): return complex(Z.real,-Z.imag) #■畑写像のための関数 def f0(Z): return A*Z+B*conj(Z) def f1(Z): return C*(Z-1)+D*(conj(Z)-1)+1 #■複素数による点描画 def drawPoint(Z): global A,B,C,D, CL, DSP, canvas FC=CL[0] if Z.imag<0: FC=CL[1] X=int(DSP[0]+Z.real*DSP[2]+0.5) Y=int(DSP[1]-Z.imag*DSP[3]+0.5) canvas.create_rectangle(X,Y,X,Y,fill=FC, outline='') #■描画 def drawRec(N,Z): if N==0: drawPoint(Z); return drawRec(N-1,f0(Z)) drawRec(N-1,f1(Z)) #■複素数文字列 def cmpStr(z): if z.imag>=0:return "%7.4f + %6.4f j" % (z.real, z.imag) return "%7.4f - %6.4f j" % (z.real, abs(z.imag)) #■パラメータ表示 def dspValue(): global A,B,C,D canvas.create_text(100,10,text="A : "+ cmpStr(A),     font=('MS ゴシック',10)) canvas.create_text(100,22,text="B : "+ cmpStr(B),     font=('MS ゴシック',10)) canvas.create_text(100,34,text="C : "+ cmpStr(C),     font=('MS ゴシック',10)) canvas.create_text(100,46,text="D : "+ cmpStr(D),     font=('MS ゴシック',10))      #■メイン処理 root=Tk(); root.title("畑政義写像") canvas=Canvas(root, width=DSP[4],height=DSP[5],bg='white') canvas.pack() canvas.delete(ALL) dspValue() drawRec(LOOP,complex(0)) root.update() root.mainloop() 9.2 おなじみのフラクタル 【リスト9-2】 (データ設定部分のみ。他は【リスト8-1】と同じ) A=complex(0.0, 0.0); B=complex(-1/2, -1/2) C=complex(0.0, 0.0); D=complex(-1/2, 1/2) DSP=[250,20,150,150, 500, 250]; CL=["#FF0000", "#FF0000"]; LOOP=15 【リスト9-3】 (データ設定部分のみ。他は【リスト8-1】と同じ) A=complex( 0.5, -0.5); B=complex(0) C=complex(-0.5, -0.5); D=complex(0) DSP=[250,120,100,100, 500, 250]; CL=["#FF0000", "#FF0000"]; LOOP=17 【リスト9-4】 (データ設定部分のみ。他は【リスト8-1】と同じ) A=complex(-0.25,0.5); B=complex(0.0, 0.0) C=complex(0.0, 0.0); D=complex(0.0, 0.7) DSP=[250,120,100,100, 500, 250] CL=["#0000FF","#0000FF"]; LOOP=15 【リスト9-5】 (データ設定部分のみ。他は【リスト8-1】と同じ) A=complex(0.7,0.1); B=complex(0.0, 0.3) C=complex(0.0, 0.2); D=complex(0.7, 0.0) DSP=[250,100,150,150, 500, 250] CL=["#FF0000","#0000FF"]; LOOP=15 【リスト9-6】 (データ設定部分のみ。他は【リスト8-1】と同じ) A=complex(0.5, -0.5); B=complex() C=complex(); D=complex(0.5, -0.5) DSP=[250,120,150,150, 500, 250] CL=["#FF0000","#0000FF"]; LOOP=15 【リスト9-7】 (データ設定部分のみ。他は【リスト8-1】と同じ) A=complex( 0.5, -0.5); B=complex(0.2, 0.0) C=complex(-0.5, -0.5); D=complex(0.0, -0.2) DSP=[200,120,100,100, 500, 250] CL=["#FF0000","#0000FF"]; LOOP=15 【リスト9-8】 (データ設定部分のみ。他は【リスト8-1】と同じ) A=complex(-0.5, 0.5); B=complex() C=complex(); D=complex(0, 0.5) DSP=[250,120,100,100, 500, 250] CL=["#FF0000","#0000FF"]; LOOP=15 【リスト9-9】 (データ設定部分のみ。他は【リスト8-1】と同じ) A=complex(0.5, 0.4); B=complex(0,0.4) C=complex(0.5,-0.4); D=complex(0, -0.4) DSP=[250,120,100,100, 500, 250] CL=["#FF0000","#0000FF"]; LOOP=15 9.3 特徴的なフラクタル 【リスト9-10】 (データ設定部分のみ。他は【リスト8-1】と同じ) A=complex(0, 0.5); B=complex() C=complex(); D=complex(0.75,0) DSP=[250,120,200,200, 500, 250]; CL=["#775500","#5555FF"]; LOOP=15 【リスト9-11】 (データ設定部分のみ。他は【リスト8-1】と同じ) A=complex(0.7, 0.2); B=complex() C=complex(); D=complex(0.67,0) DSP=[220,80,250,250, 500, 250] CL=["#007700","#007700"]; LOOP=15 【リスト9-12】 (データ設定部分のみ。他は【リスト8-1】と同じ) A=complex(0.7, 0.2); B=complex() C=complex(); D=complex(0.67,0) DSP=[220,80,250,250, 500, 250];CL=["#007700","#007700"]; LOOP=15 【リスト9-13】(データ設定部分のみ。他は【リスト8-1】と同じ) A=complex(0.7, 0.2); B=complex() C=complex(); D=complex(0.67,0) DSP=[220,80,250,250, 500, 250];CL=["#007700","#007700"]; LOOP=15 【リスト9-14】(データ設定部分のみ。他は【リスト8-1】と同じ) A=complex(0.1); B=complex(0.5, 0.3) C=complex(0.1); D=complex(0.67) DSP=[220,80,250,250, 500, 250];CL=["#007700","#557700"]; LOOP=15   【リスト9-15】(データ設定部分のみ。他は【リスト8-1】と同じ) A=complex(0.55, -0.45); B=complex(); C=complex(0.80, 0.20); D=complex() DSP=[250,40,150, 150, 500, 250]; CL=["#5555FF","#5555FF"]; LOOP=15 【リスト9-16】(データ設定部分のみ。他は【リスト8-1】と同じ) A=complex(0.67, -0.5); B=complex(); C=complex(-0.25, 0.5); D=complex() DSP=[300,70,100, 100, 500, 250];CL=["#007700","#007700"]; LOOP=15 【リスト9-17】(データ設定部分のみ。他は【リスト8-1】と同じ) A=complex(); B=complex(0.45, 0.5) C=complex(); D=complex(0.45, -0.5) DSP=[160,160,300, 300, 500, 250]; CL=["#773300","#773300"]; LOOP=15 【リスト9-18】(データ設定部分のみ。他は【リスト8-1】と同じ) A=complex(0.2); B=complex(-0.5, -0.5) C=complex(-0.5, -0.5); D=complex(-0.2) DSP=[200,120,80, 80, 500, 250] CL=["#FF0000","#FF0000"]; LOOP=15 【リスト9-19】(データ設定部分のみ。他は【リスト8-1】と同じ) A=complex(0.5, -0.5); B=complex(0.2) C=complex(-0.25, 0.5); D=complex() DSP=[240,60,150, 150, 500, 250] CL=["#007700","#007700"]; LOOP=15 【リスト9-20】(データ設定部分のみ。他は【リスト8-1】と同じ) A=complex(0.8, 0.2); B=complex(0.0, 0.2) C=complex(0.0, 0.2); D=complex(0.6, 0.1) DSP=[240,90,100, 100, 500, 250] CL=["#FF0000","#FF0000"]; LOOP=15 【リスト9-21】(データ設定部分のみ。他は【リスト8-1】と同じ) A=complex(); B=complex(0.5, 0.7); C=complex(); D=complex(0.7) DSP=[240,80,100, 100, 500, 250]; CL=["#007700","#007700"]; LOOP=15 【リスト9-22】(データ設定部分のみ。他は【リスト8-1】と同じ) A=complex(0.1); B=complex(0.0, 0.7); C=complex(0.1); D=complex(0.0, -0.7) DSP=[240,120,150, 150, 500, 250]; CL=["#FF0000","#FF0000"]; LOOP=15 9.4 写像の拡張 【リスト9-23】 拡張方式によるコッホ曲線 from tkinter import * import math,copy #■データ定義 # # ① DSP=[X0, Y0, SX, SY, width, height] # # X0, Y0 : 表示開始位置 # SX, SY : XY方向スケール # Width, height : キャンバスの幅と高さ # # ② その他 # MT[][]: 計算用パラメータ # CL[0]: キャンバス背景色 # CL[1]: パラメータ表示の際の文字列色 #コッホ曲線 s36=math.sqrt(3)/6 MT=((complex(),complex(1/2, s36),complex()), (complex(),complex(1/2, -s36),complex(1/2, s36))) DSP=(80,160,300,300, 500, 200); CL=("white", "black");LOOP=14 #■共役複素数 def conj(Z): return complex(Z.real,-Z.imag) #■RGB値の範囲内に収める def cVal(D): #print(D) R=int(D*255) if R<0: return 0 if R>255: return 255 return R #■R/G/Bを Python 用色コードに変換 def setColor(C): return "#%02X%02X%02X" % (cVal(C[0]),cVal(C[1]),cVal(C[2])) #■複素数による点描画 def drawPoint(Z, cT): global DSP, canvas X=int(DSP[0]+Z.real*DSP[2]+0.5) Y=int(DSP[1]-Z.imag*DSP[3]+0.5) canvas.create_rectangle(X,Y,X,Y,fill=setColor(cT), outline='') #■描画 def drawRec(N, Z, CC): global MT if N==0: drawPoint(Z, CC); return NL=len(MT); m=math.pow(2,-N) for i in range(NL): MD = i % 3; CC[MD]+=m #色分け処理 drawRec(N-1, MT[i][0]*Z+MT[i][1]*conj(Z)+MT[i][2],CC) CC[MD]-=m #■複素数の文字列化 def cmpStr(z): if z.imag>=0:return "%7.4f + %6.4f j" % (z.real, z.imag) return "%7.4f - %6.4f j" % (z.real, abs(z.imag)) #■パラメータの表示 def dspValue(): global MT,DSP canvas.create_text(250,12, #基準表示位置(X0, Y0), XYスケール text=(("X0 = %7.0f Y0 = %7.0f "+ "Scale = (%7.0f, %7.0f)") % (DSP[0], DSP[1], DSP[2], DSP[3])), font=('MS ゴシック',10), fill=CL[1]) NL=len(MT) for i in range(NL): canvas.create_text(250,i*12+30, #計算用パラメータ text=(cmpStr(MT[i][0])+", "+ cmpStr(MT[i][1])+", "+ cmpStr(MT[i][2])), font=('MS ゴシック',10), fill=CL[1]) #■メイン処理 root=Tk(); root.title("畑政義写像の拡張") canvas=Canvas(root, width=DSP[4],height=DSP[5],bg=CL[0]); canvas.pack() canvas.delete(ALL); dspValue() drawRec(LOOP,complex(0),[0,0,0]) root.update(); root.mainloop() 【リスト9-24】 拡張方式による葉模様(データ定義のみ) MT=((complex(0.7,0.2),complex(),complex()), (complex(),complex(0.67),complex(0.33))) DSP=(160,130,250,250, 500, 200); CL=("white", "black"); LOOP=14 【リスト9-25】 拡張方式によるモスモンスター(データ定義のみ) MT=((complex(0.67,-0.5),complex(),complex()), (complex(-0.25,0.5),complex(),complex(1.25,-0.5))) DSP=(200,130,100,100, 500, 300); CL=("white", "black"); LOOP=15 【リスト9-26】 拡張方式による規則的なひび割れ(データ定義のみ) MT=((complex(),complex(0.45, 0.5),complex()), (complex(),complex(0.45, -0.5),complex(0.55, 0.5))) DSP=(120,230,300,300,500, 300); CL=("white", "black"); LOOP=14 【リスト9-27-1】 拡張方式によるシェルピンスキのギャスケット(データ定義のみ) s34=math.sqrt(3)/4 MT=((complex(0.5),complex(),complex()), (complex(0.5),complex(),complex(0.5)), (complex(0.5),complex(),complex(0.25, s34 ))) DSP=(200,200,150,150, 500, 300); CL=("white", "black") ;LOOP=8 【リスト9-27-2】 拡張方式によるカントールの塵(データ定義のみ) s1=1/3; s2=2/3 MT=((complex(s1),complex(),complex(0 , 0 )), (complex(s1),complex(),complex(s2, 0 )), (complex(s1),complex(),complex(0 , s2)), (complex(s1),complex(),complex(s2, s2))) DSP=(200,250,150,150, 500, 300); CL=("white", "black") ;LOOP=9 【リスト9-27-3】 拡張方式によるシェルピンスキのカーペット(データ定義のみ) S1=1/3; S2=2/3 #以下, 反時計回りに指定 MT=((complex(S1),complex(),complex(0 , 0 )), (complex(S1),complex(),complex(S1, 0 )), (complex(S1),complex(),complex(S2, 0 )), (complex(S1),complex(),complex(S2, S1)), (complex(S1),complex(),complex(S2, S2)), (complex(S1),complex(),complex(S1, S2)), (complex(S1),complex(),complex(0 , S2)), (complex(S1),complex(),complex(0 , S1))) DSP=(200,280,150,150, 500, 300); CL=("white", "black"); LOOP=5 【リスト9-27-4】 拡張方式による雪の結晶(データ定義のみ) S1=1/3; S2=2/3 MT=((complex(S1),complex(),complex(S1, S1)), (complex(S1),complex(),complex(S1, S2)), (complex(S1),complex(),complex(S1, 0 )), (complex(S1),complex(),complex(S2, S1)), (complex(S1),complex(),complex(0 , S1))) DSP=(200,280,180,180, 500, 300); CL=("white", "black"); LOOP=6 【リスト9-28-1】 図9-30の(a)(データ定義のみ) s36=math.sqrt(3)/6 MT=((complex(1), complex(), complex(1,0)), (complex(),complex(1/2, s36),complex()), (complex(),complex(1/2, -s36),complex(1/2, s36))) DSP=(0,300,100,100, 500, 500); CL=("white", "black");LOOP=12 #14 【リスト9-28-2】 図9-30の(b)(データ定義のみ) s36=math.sqrt(3)/6 MT=((complex(0.5), complex(), complex(1,0)), (complex(),complex(1/2, s36),complex()), (complex(),complex(1/2, -s36),complex(1/2, s36))) DSP=(50,200,200,200, 500, 300); CL=("white", "black");LOOP=11 【リスト9-28-3】 図9-30の(c)(データ定義のみ) s36=math.sqrt(3)/6 MT=((complex(),complex(-1/2, -s36),complex()), (complex(),complex( 1/2, s36),complex()), (complex(),complex( 1/2, -s36),complex(1/2, s36))) DSP=(200,200,200,200, 500, 300); CL=("white", "black");LOOP=11 【リスト9-28-3】 図9-30の(d)(データ定義のみ) s36=math.sqrt(3)/6 MT=((complex(),complex(-1/2, -s36),complex(1/2, s36)), (complex(),complex( 1/2, s36),complex()), (complex(),complex( 1/2, -s36),complex(1/2, s36))) DSP=(100,220,300,300, 500, 300); CL=("white", "black");LOOP=11 【リスト9-29】 図9-31(データ定義のみ) MT=((complex(0.5),complex(),complex(1)), (complex(),complex(0.45, 0.5),complex()), (complex(),complex(0.45, -0.5),complex(0.55, 0.5))) DSP=(120,210,120,120, 500, 300); CL=("white", "black"); LOOP=11