2.1 コッホ曲線の変形 【リスト2-1】 ランダムなコッホ曲線 from tkinter import * import math, random curX=0; curY=0; Theta=0; PI=math.pi def t_pos(X, Y): global curX, curY; curX = X; curY = Y def t_deg(T) : global Theta; Theta = T def t_turn(T) : global Theta; Theta += T def t_forward(length): global curX, curY, Theta, PI,canvas TH = Theta * PI / 180; X = curX+length*math.cos(TH) Y = curY+length*math.sin(TH) canvas.create_line(curX, 200 - curY, X, 200 - Y, width=3, fill="#FF0000") curX=X; curY=Y def koch(n, length): if n<=0: t_forward(length); return #方向、長さともに乱数を発生させて進む R1=(random.random()+1)*0.2; R2=(random.random()+1)*0.2 R3=1-(R1+R2) T1=60*random.random();T2=-120*random.random() T3=-(T1+T2) nn=n -1 ; koch(nn,length*R1) t_turn(T1); koch(nn,length*R2) t_turn(T2); koch(nn,length*R2) t_turn(T3); koch(nn,length*R3) def leftMouseDown(event):#ダウン canvas.delete(ALL) t_pos(0,0); t_deg(0); koch(5,200) root=Tk(); root.title("Random Koch") canvas=Canvas(root, width=580, height=558,bg="white") canvas.pack() leftMouseDown(0) canvas.bind("",leftMouseDown) root.mainloop()   【リスト2-2】 ランダム島の生成 from tkinter import * import math, random, copy X0=350; Y0=350 # 島中央の座標 R0=50 # Y = 0のときの半径 curX=0; curY=0; Theta=0; PI=math.pi def t_pos(X, Y): global curX, curY; curX = X; curY = Y def t_deg(T) : global Theta; Theta = T def t_turn(T) : global Theta; Theta += T def t_forward(length): global curX, curY, Theta, PI,canvas TH = Theta * PI / 180; X = curX+length*math.cos(TH); Y = curY+length*math.sin(TH) canvas.create_line(curX, 200 - curY, X, 200 - Y, width=3, fill="#FF0000") curX=X; curY=Y hist.append(copy.copy(X));hist.append(copy.copy(Y)); def koch(n, length): if n<=0: t_forward(length); return R1=(random.random()+1)*0.2; R2=(random.random()+1)*0.2 R3=1-(R1+R2) T1=60*random.random();T2=-120*random.random() T3=-(T1+T2) nn=n -1; koch(nn,length*R1) t_turn(T1); koch(nn,length*R2) t_turn(T2); koch(nn,length*R2) t_turn(T3); koch(nn,length*R3) def randomKochIland(): global hist,canvas canvas.delete(ALL) hist=[0,0];t_pos(0,0); t_deg(0); koch(5, 200) LM=len(hist);NM=int(LM/2) DY=(hist[LM-1]-hist[1])/NM/2 ii=3 for i in range(NM-1): hist[ii]-=DY*(ii-2); ii+=2 ii=0 for i in range(NM-1): canvas.create_line(hist[ii], 200 - hist[ii+1], hist[ii+2], 200 -hist[ii+3], width=3, fill="#007700") ii+=2 canvas.create_line(hist[0], 200 - hist[1], hist[LM-2], 200 -hist[LM-1], width=2, fill="#0000FF") PDT=[0 for i in range(LM)] ii=0;dth=2*PI/hist[LM-2] for i in range(NM): th=dth*hist[ii] PDT[ii ]=X0+(R0+hist[ii+1])*math.cos(th) PDT[ii+1]=Y0+(R0+hist[ii+1])*math.sin(th) ii+=2 canvas.create_polygon(PDT, fill="#FFFF77", outline="#FF7700", width=3) root.update() def leftMouseDown(event):#ダウン randomKochIland() root=Tk(); root.title("Random Koch and The Island") canvas=Canvas(root, width=580, height=558,bg="white") canvas.pack() randomKochIland() canvas.bind("",leftMouseDown) root.mainloop() 【リスト2-3】 カラフルなコッホ雪片 from tkinter import * import math class RelativeDraw: #■ コンストラクタ def __init__(self, canvas,startX, startY,scaleX, scaleY, lineWidth,color): self.canvas=canvas self.X0=startX; self.Y0=startY self.SX=scaleX; self.SY=scaleY self.lineWidth=linewidth; self.color=color self.goto(0,0) #■ XY座標設定 def goto(self,x,y): self.x=x; self.y=y #■ カラー設定 def setColor(self,color): self.color=color #■ 線幅設定 def setWidth(self,lineWidth): self.lineWidth=lineWidth #■ スクリーン座標への変換 def screenX(self, X): return self.X0 + self.SX * X def screenY(self, Y): return self.Y0 + self.SY * Y class TurtleGraph(RelativeDraw): #■ コンストラクタ def __init__(self, canvas,startX, startY,scaleX, scaleY, lineWidth,color): RelativeDraw.__init__(self,canvas,startX, startY,scaleX, scaleY, lineWidth,color) self.setAng(0) #■ 角度設定 def setAng(self,th): self.th=th #■ 向きの変更(右回転は負の値で指定) def turn(self,th): self.th=self.th+th #■ 前に進む(後退は負の値で指定) def forward(self,L): TH=self.th*math.pi/180 X=self.x+L*math.cos(TH);Y=self.y+L*math.sin(TH) self.canvas.create_line(self.screenX(self.x), self.screenY(self.y), self.screenX(X) , self.screenY(Y) , width = self.lineWidth, fill = self.color) self.x=X; self.y=Y #■コッホ曲線のクラス定義(turtleGraph, RelativeDrawクラスからの継承) class Koch(TurtleGraph): def curve(self,N,L,DA): if N<=0: self.forward(L) else: NN=N-1; LL=L/3 L2=LL/(2*math.cos(DA*math.pi/180)) self.curve(NN,LL,DA) self.turn(DA) ; self.curve(NN,L2,DA) self.turn(-2*DA); self.curve(NN,L2,DA) self.turn(DA) ; self.curve(NN,LL,DA) #■ tkinter,Canvas共通処理 def initTk(Title): tk=Tk(); tk.title(Title); return tk def initCanvas(W,H): canvas=Canvas(tk,width=W,height=H); canvas.pack() return canvas #■ メイン処理 tk=initTk("Koch雪片")#Koch snowflake canvas=initCanvas(220,250) koch=Koch(canvas, 10, 65, 1, -1, 2, 'blue') DT=60; MX=205; NL=5 CTab=["#FF0000","#FF7700","#FFFF00","#77FF00","#00FF00","#007700", "#007777","#0077FF","#0000FF","#7700FF","#770077","#FF0077",] koch.setWidth(3) for DT in range(-60,60): koch.setColor(CTab[int(abs(DT)/4) % 12]) for k in range(3): koch.setAng(-120*k);koch.curve(NL,MX,DT) tk.update() koch.setWidth(1); koch.setColor('#00FF00') for k in range(3): koch.setAng(-120*k);koch.curve(NL,MX,-60) koch.setColor('#770000') for k in range(3): koch.setAng(-120*k);koch.curve(NL,MX,60) tk.update() tk.mainloop()   図2-4(b)は,描画の部分を以下のように変更したものです。 ・ ・(前略) ・ koch.setWidth(3) for DT in range(-60,60): #CD=255-abs(DT)*4 CD=135+DT*2 C="#%02X%02XFF" % (CD, 195+DT) koch.setColor(C) for k in range(3): koch.setAng(-120*k);koch.curve(NL,MX,DT) tk.update() koch.setWidth(1) koch.setColor('#FFFFFF') for k in range(3): koch.setAng(-120*k);koch.curve(NL,MX,-60) tk.update() ・ ・(後略) ・ 2.2 立ち枯れ木立 【リスト2-4】立ち枯れ木立をTurtleグラフィックスで描く import turtle def blightTree(t,L,angTB,forTB): if L<2.0: t.forward(L) else: for j in range(0,4): t.left(angTB[j]); blightTree(t,L*forTB[j],angTB,forTB) #■メイン処理 t=turtle.Pen() t.screen.title("Blighted Tree used Turtle graphics") t.speed(0)#タートル移動を速くする t.screen.tracer(100000,0)#描く順序を見たいとき第1引数を小さくする t.hideturtle()#タートルを見えなくする t.up(); t.goto(-300,100);t.down()#描画開始位置に移動 t.width(1); t.color('#883300')#線幅とカラーを設定 angTB=[0.0, 88.0, -176.0, 88.0]#テーブル設定 forTB=[0.28, 0.28, 0.28, 0.7] blightTree(t,420,angTB,forTB)#立ち枯れ木立描画開始 t.screen.tracer(1,0) t.screen.mainloop() 【リスト2-5】 tkinterモジュールによる立ち枯れ木立 from tkinter import * import math from tkinterTurtle import * #■ 立ち枯れ木立のクラス定義 # (curve, angTB, forTB以外はTurtleGraph,RelativeDrawクラスからの継承) class BlightedTree(TurtleGraph): #■ コンストラクタ def __init__(self, canvas,startX, startY,scaleX, scaleY, lineWidth,color): TurtleGraph.__init__(self,canvas,startX, startY,scaleX, scaleY, lineWidth,color) self.angTB=[0, 88, -176, 88] self.forTB=[0.28, 0.28, 0.28, 0.7] def curve(self,L): if L<=2.0: self.forward(L) else: for j in range(0,4): self.turn(self.angTB[j]) self.curve(L*self.forTB[j]) #■ tkinter,Canvas共通処理 def initTk(Title): tk=Tk() tk.title(Title) return tk def initCanvas(W,H): canvas=Canvas(tk,width=W,height=H) canvas.pack() return canvas #■ メイン処理 tk=initTk("Blighted Tree used tkinter") canvas=initCanvas(600,300) tree=BlightedTree(canvas, 50, 200, 1, -1, 1, '#883300') ELM0=[0, 88, -176, 88] ELM1=[0.28, 0.28, 0.28, 0.7] tree.curve(420) tk.mainloop() 2.3 平面の自己相似形 【リスト2-6】 平面の自己相似形の生成と表示 from tkinter import * from landColor import * from hiddenLine import * def setData(N, X,Y, H, K): if K==0: return if N<3: return NN=N/3; N1=int(NN); N2=int(NN*2) for j in range(X+N1, X+N2): for i in range(Y, Y+N): Z[j][i] += H for j in range(Y+N1, Y+N2): for i in range(X, X+N): Z[i][j] += H setData(N1,X , Y , H, K-1); setData(N1,X+N1, Y , H, K-1); setData(N1,X+N2, Y , H, K-1); setData(N1,X , Y+N1, H, K-1); setData(N1,X+N1, Y+N1, H, K-1); setData(N1,X+N2, Y+N1, H, K-1); setData(N1,X , Y+N2, H, K-1); setData(N1,X+N1, Y+N2, H, K-1); setData(N1,X+N2, Y+N2, H, K-1); def setDataStart(canvas): global Z, arroundV, middleV, Steep, seaFlag, NumX, NumY for j in range(NumX+1): # 周辺を初期設定 for i in range(NumY+1):Z[j][i] = 0 setData(NumX,0,0,1, 3) for j in range(NumX+1): # 周辺を初期設定 for i in range(NumY+1):Z[j][i] *= 5 T=[[0 for j in range(NumX+1)] for i in range(NumY+1)] for i in range(5): for j in range(NumX+1): for k in range(NumY+1): T[j][k] =Z[j][k] for j in range(1, NumX): Z[j][0] =(T[j-1][0]+T[j+1][0]+T[j][1]+T[j][0]*2)/5 for k in range(1, NumY): Z[j][k]=(T[j-1][k]+T[j+1][k]+T[j][k-1]+ T[j][k+1]+ T[j][k]*2)/6 hiddenLine(canvas) #等高線図のときはdrawContour(canvas)とする root=Tk(); root.title("平面の自己相似形"); root.geometry("460x460") canvas=Canvas(root, width=460,height=460); canvas.place(x=0,y=100) setDataStart(canvas); root.mainloop() 【リスト2-7】 カラー設定用クラス等(ファイル名をlandColor.pyとする) #■範囲チェック def rangeD(D, D1, D2): if DD2: return D2 return D #■色のクラス class Color: def __init__(self, R=0, G=0, B=0, ColorSV=0.5): self.R=R self.G=G self.B=B self.ColorSV=ColorSV #■標高値による色の設定 def setColorElm(self, R): if R >= 512: return Color(255, 0, 0, self.ColorSV) if R >= 384: return Color(255, 255 - 2 * (R - 384), 0, self.ColorSV) if R >= 256: return Color((R - 256) * 2, 255, 0, self.ColorSV) if R >= 128: return Color(0, R, 0, self.ColorSV) if R < 0 : if R < -510 : return Color(255, 127, 127, self.ColorSV) return Color(-int(R / 2), -int(R / 4), 127, self.ColorSV ) return Color(0, R, 177 - R, self.ColorSV) def setColor(self,Z, N): SZ = 0 for i in range(N): SZ += Z[i] R = int((SZ / (N * 4) + 1.001) * self.ColorSV * 127) return self.setColorElm(R) #■Python用色指定に変換 def toString(self): R=rangeD(self.R, 0, 255) G=rangeD(self.G, 0, 255) B=rangeD(self.B, 0, 255) return "#%02X%02X%02X" % (R,G,B) 【リスト2-8】 陰線消去・等高線表示(ファイル名をhiddenLine.pyとする) from tkinter import * from landColor import * import math #■Python用配列宣言 def array(N1, N2=0, N3=0): if N2 == 0 and N3==0: return [0 for i in range(N1)] elif N3 == 0: return [[0 for i in range(N2)] for j in range(N1)] else: return [[[0 for i in range(N3)] for j in range(N2)] for k in range(N1)] #■初期設定 NumX = 64; NumY = 64 Z=array(NumX + 1, NumY + 1) # 隠し線処理/表示用値 PI=math.pi dlx = 0.1; alpha = PI / 12; beta = PI / 8; dx = 2; dy = 1.4 dxCosA = dx * math.cos(alpha) ; dyCosB = dy * math.cos(beta) dxSinA = dx * math.sin(alpha) ; dySinB = dy * math.sin(beta) Xlen = (NumX - 1) * dxCosA ; Ylen = (NumY - 1) * dyCosB dlxTanA = dlx * math.tan(alpha); dlxTanB = dlx * math.tan(beta) ZeroP = 0.5 #■共通関数 def GroundX(j, k): global dxCosA, dyCosB; return dxCosA * j - dyCosB * k def GroundY(j, k): global dxSinA, dySinB; return dxSinA * j + dySinB * k def DrawPos(j, k): global Ylen, dlx; return (0.5 + (Ylen + GroundX(j, k) / dlx)) def setPx(j, k, X0, PH): global dlx;return PH * dlx + GroundX(j, k) + X0 def setPy(j, k, Y0, PH, fp): global dlxTanA; return PH * dlxTanA + GroundY(j, k) + fp + Y0 #--------------描画用関数----------------------------------- #■スクリーン座標系変換 def screenX(X): return int(20 + X * 2 + 0.5) def screenY(Y): return int(400 - Y * 2 + 0.5) #■四角形描画 def drawTetragon(canvas, X, Y, C, CC): p=[] for i in range(4): p.append(screenX(X[i])); p.append(screenY(Y[i])) canvas.create_polygon(p,fill=C.toString(), outline=CC.toString(), tag="DT") #■有効標高値の設定 def getZ(j, k): global Z, seaFlag; R = Z[j][k] if R > -999: return Z[j][k] for jj in range(j-1, j+2): for kk in range(k-1, k+2): if Z[jj][kk] >-999 and Z[jj][kk]=1: j=NumX-2 while j>=1: if(Z[j][ k ] > -999 or Z[j-1][ k ] > -999 or Z[j][k-1] > -999 or Z[j-1][k-1] > -999 ): #標高値なしを省く RX = setSquareXYZ(X0, Y0, j, k) AX = RX[0]; AY=RX[1]; AZ=RX[2] C=CC.setColor(AZ,4) drawTetragon(canvas, AX, AY, C, Color(0,0,0)) #四角形枠線描画 j -= 1 k -= 1 #■カラーマップ表示 def colorMap(canvas): global NumX, NumY,Z canvas.delete(ALL); CC=Color(0,0,0); SC=5 for k in range(1, NumY): Y1=(NumY-k+1)*SC; Y2=(NumY-k)*SC for j in range(1, NumX): X1=j*SC+70; X2=X1+SC+1 R = int((Z[j][k]/4 + 1.001) * CC.ColorSV * 127) C=CC.setColorElm(R) canvas.create_rectangle(X1,Y1,X2,Y2,fill=C.toString(), outline=C.toString(), tag="DT") def interpo(H, Z1, Z2): return ((H-Z1)/(Z2-Z1)) def drawCline(canvas, x1, y1, x2, y2,C): global NumX, NumY,Z; SC=5.0 X1=int((x1+1)*SC+70); X2=int((x2+1)*SC+70) Y1=int((NumY-y1)*SC); Y2=int((NumY-y2)*SC) canvas.create_line(X1,Y1,X2,Y2,fill=C, tag="DT") def contour1cell(canvas, j,k,H): global NumX, NumY,Z Z0 = Z[j][k]; Z1 = Z[j+1][k ] Z2 = Z[j+1][k+1]; Z3 = Z[j ][k+1] P01 = (Z0> H) != (Z1 > H); P12 = (Z1> H) != (Z2 > H) P23 = (Z2> H) != (Z3 > H); P30 = (Z3> H) != (Z0 > H) C="#000000" if P01 or P12 or P23 or P30: x0=0; y1=0; x2=0; y3=0 if P01: x0 = (float(j)+interpo(H, Z0,Z1)) if P12: y1 = (float(k)+interpo(H, Z1,Z2)) if P23: x2 = (float(j)+interpo(H, Z3,Z2)) if P30: y3 = (float(k)+interpo(H, Z0,Z3)) yk = (float(k )); yk1= (float(k+1)) xj = (float(j )); xj1= (float(j+1)) if P01 and P12: drawCline(canvas, x0 , yk , xj1, y1 ,C) if P12 and P23: drawCline(canvas, xj1, y1 , x2 , yk1,C) if P23 and P30: drawCline(canvas, x2 , yk1, xj , y3 ,C) if P30 and P01: drawCline(canvas, xj , y3 , x0 , yk ,C) if P01 and P23: drawCline(canvas, x0 , yk , x2 , yk1,C) if P12 and P30: drawCline(canvas, xj1, y1 , xj , y3 ,C) def contourAll(canvas, v1, v2,dv): global NumX, NumY for j in range(NumX-1): for k in range(NumY-1): v=v1 while v<=v2: contour1cell(canvas, j,k,v); v+=dv def minZ(): global NumX, NumY, Z; m=Z[0][0] for j in range(NumX-1): for k in range(NumY-1): if Z[j][k]m: m=Z[j][k] return m def drawContour(canvas): canvas.delete(ALL) V1 = minZ(); V2 = maxZ() if abs(V2-V1) < 0.0000001: V2 = V1 + 1 colorMap(canvas); Hstep=1 contourAll(canvas,V1, V2, Hstep) 2.4 ランダム地形   【リスト2-9】 ランダム地形 from tkinter import * from tkinter import messagebox from tkinter import filedialog from tkinter import scrolledtext from landColor import * from hiddenLine import * import os, random, math # 地形生成用値 seaFlag = True # 負の標高値のとき 0 にするときTrue(チェックボタンで指定) Steep = 0.5 # 地形の険しさ(テキストボックスで指定) middleV = 0.0 # 中央の初期値(テキストボックスで指定) arroundV = 0.0 # 周辺の初期値(テキストボックスで指定) #■ランダム地形生成 def setMap(L, U, W, dH): global Zerop, Z, Steep if W < 2 : return DW = W; WW = int(DW / 2); RZ = 1 - ZeroP Z[L+WW][U] = (Z[L+W][U] + Z[L][U]) * 0.5 + dH * (random.random() - RZ) Z[L+WW][U+W] = (Z[L+W][U+W] + Z[L][U+W]) * 0.5 + dH * (random.random() - RZ) Z[L][U + WW] = (Z[L][U] + Z[L][U+W]) * 0.5 + dH * (random.random() - RZ) Z[L+W][U+WW] = (Z[L+W][U+W] + Z[L+W][U]) * 0.5 + dH * (random.random() - RZ) Z[L+WW][U+WW]= (Z[L+WW][U] + Z[L+WW][U+W]+Z[L][U+WW]+           Z[L+W][U+WW])*0.25+dH *(random.random()-RZ)* 0.5 setMap(L , U , WW, dH * Steep) # 左上生成 setMap(L + WW, U , WW, dH * Steep) # 右上生成 setMap(L , U + WW, WW, dH * Steep) # 左下生成 setMap(L + WW, U + WW, WW, dH * Steep) # 右下生成 #■標高値データの初期設定とランダム地形生成呼び出し def setData(): global Z, arroundV, middleV, Steep, seaFlag, NumX, NumY for j in range(NumX+1): # 周辺を初期設定 Z[j][ 0 ] = arroundV; Z[j][NumY] = arroundV for j in range(NumY+1): Z[ 0 ][j] = arroundV; Z[NumX][0] = arroundV DW =float(NumX); WW = int(DW / 2) Z[WW][WW] = middleV # 中央を初期設定 setMap( 0, 0, WW, Steep) # 左上生成 setMap(WW, 0, WW, Steep) # 右上生成 setMap( 0, WW, WW, Steep) # 左下生成 setMap(WW, WW, WW, Steep) # 右下生成 for i in range(1,6): # 平均化することで刺々しさを緩和する for k in range(1,NumY): Z[0][k] = (Z[1][k] + Z[0][k-1] + Z[0][k+1] + Z[0][k] * 2) / 5 for j in range(1,NumX): Z[j][0] = (Z[j-1][0] + Z[j+1][0] + Z[j][1] + Z[j][0] * 2) / 5 for k in range(1, NumY): Z[j][k] = (Z[j-1][k] + Z[j+1][k] + Z[j][k-1] + Z[j][k+1] + Z[j][k] * 2) / 6 for j in range(NumX+1): # 負の標高値を0にし、かつ標高値を100倍する for k in range(NumY+1): if seaFlag and Z[j][k] < 0: Z[j][k] = 0 Z[j][k] *= 100 #■中央点を周辺4点の平均値からのズレとするアルゴリズム def setMap2(L, U, W, dH): if W<2 :return; WW = int(W / 2) Z[L+WW][U+WW] = (Z[L][U]+Z[L+W][U]+Z[L][U+W]+Z[L+W][U+WW])*0.25+           dH*(random.random()-0.5); Z[L+WW][U ] = (Z[L ][U ]+Z[L+W][U ])*0.5+dH*(random.random()-0.5); Z[L+WW][U+W ] = (Z[L ][U+W]+Z[L+W][U+W])*0.5+dH*(random.random()-0.5); Z[L ][U+WW] = (Z[L ][U ]+Z[L ][U+W])*0.5+dH*(random.random()-0.5); Z[L+W ][U+WW] = (Z[L+W][U ]+Z[L+W][U+W])*0.5+dH*(random.random()-0.5); setMap2(L ,U ,WW,dH* Steep) setMap2(L+WW,U ,WW,dH* Steep) setMap2(L ,U+WW,WW,dH* Steep) setMap2(L+WW,U+WW,WW,dH* Steep) def addFunc(): global Z, arroundV, middleV, Steep, seaFlag, NumX, NumY for i in range(NumX+1): ii=float(i-NumX/4)/float(NumX); Di=ii*ii; for j in range(NumY+1): jj= float(j-NumY/4)/float(NumY); Dj=jj*jj HH=math.exp(-math.sqrt(Di+Dj)*0.1)*middleV*10+arroundV #print(HH,Z[i][j]) Z[i][j] +=HH; def setData2(): for i in range(NumX+1): for j in range(NumY+1):Z[i][j]=0 setMap2(0,0, NumX,10) addFunc() HH=0; NN=0 for j in range(NumX+1): # 標高平均値を求める for k in range(NumY+1): HH +=Z[j][k]; NN+=1 HH /=NN for j in range(NumX+1): # 標高平均値を差し引く for k in range(NumY+1): Z[j][k]-=HH for k in range(5): for i in range(1,NumX): for j in range(1, NumY): Z[i][j]=(Z[i-1][j-1]+Z[i-1][j]+Z[i-1][j+1]+Z[i][j-1]+Z[i][j]+ Z[i+1][j]+Z[i+1][j-1]+Z[i+1][j]+Z[i+1][j+1])/9; for j in range(NumX+1): # 負の標高値を0にし、かつ標高値を100倍する for k in range(NumY+1): if seaFlag and Z[j][k] < 0: Z[j][k] = 0 Z[j][k] *= 10 def contour(): drawContour(canvas) root.update() def redraw(): hiddenLine(canvas) root.update() #■地形の表示 def drawLand(): global opt1,seaFlag, Steep, arroundV,middleV Steep = float(textBox1.get("1.0",END)) # 地形の険しさ ( 0.0~1.0) arroundV = float(textBox2.get("1.0",END)) # 周囲の標高初期値(-1.0~1.0) middleV = float(textBox3.get("1.0",END)) # 中央の標高初期値(-1.0~1.0) seaFlag = opt1.get() # 標高負のとき0にするかどうか if method.get()==0: setData() # 地形の生成 else : setData2() hiddenLine(canvas) # 地形表示(隠れ線の処理) root.update() #■ファイル出力 def outData(): global NumX, NumY,Z fn=filedialog.asksaveasfilename(filetypes=[('Text Files', '*.txt'), ('CSV Files', '*.csv'), ('All Files', '*.*')]) if fn: try: s="" for i in range(NumY+1): s += "%12.4E" % Z[i][0] for j in range(NumX+1): s += ", %12.4E" % Z[i][j] s=s+ "\n" f=open(fn,'w'); f.write(s);f.close() except: print("出力/変換時にエラーが起きました") #■ファイル入力 def inputData(): global NumX, NumY,Z fn=filedialog.askopenfilename(filetypes=[('Text Files', '*.txt'), ('CSV Files', '*.csv'), ('All Files', '*.*')]) if fn: try: f=open(fn,'rt'); s=f.read(); f.close() for i in range(NumY): for j in range(NumX): Z[i][j]=-999 dt=""; i=0; j=0; N=len(s); k=0 while i<=NumY and k