本文实例为大家分享了Python生成树形图案的具体代码,供大家参考,具体内容如下
先看一下效果,见下图。
上面这颗大树是使用Python + Tkinter绘制的,主要原理为使用分形画树干,树枝,最终叶节点上画上绿色圆圈代表树叶。当然,为了看起来更真实,绘制过程中也加入了一些随机变化,比如树枝会稍微有些扭曲而不是一条直的线,分叉的角度,长短等都会随机地作一些偏移等。
以下是完整源代码:
# - * -编码:utf - 8 - * 进口Tkinter 导入系统,随机的,数学 类点(对象): def __init__(自我,x, y): 自我。x=x 自我。y=y def __str__(自我): 返回“& lt; Point>:(% f % f)”%(自我。x, self.y) 类分支(对象): def __init__(自我,底部、顶部、树枝、级别=0): 自我。底=底部 自我。前=前 自我。级别=自我。分支=分支 自我。孩子=[] def __str__(自我): s=": % s,底部:% s,儿童数:% d %/(自我。,自我。底,len (self.children)) 返回年代 def nextGen(自我,n=1, rnd=1): 如果n & lt;=0: n=self.branches 如果rnd==1: n=随机的。randint (n/2 n * 2) 如果n & lt;=0: n=1 dx=self.top。x - self.bottom.x dy=self.top。y - self.bottom.y r=0.20 + random.random () * 0.2 如果self.top。x==self.bottom.x: #如果是一条竖线 x=self.top.x y=dy * r + self.bottom.y elif self.top。y==self.bottom.y: #如果是一条横的线 x=dx * r + self.bottom.x y=self.top.y 其他: x=dx * r y=x * dy/dx x +=self.bottom.x y +=self.bottom.y oldTop=self.top 自我。顶级=点(x, y) 一个=数学。π/(2 * n) 因为我在范围(n): a2=- * (n - 1)/2 + *我- math.pi a2 *=0.9 + random.random () * 0.2 self.children.append (self.mkNewBranch(自我。前,oldTop a2)) def mkNewBranch(自我,底部,顶部,一个): dx1= - bottom.x ?= - bottom.y r=0.9 + random.random () * 0.2 c=数学。√dx1 * * 2 +?* * 2) * r 如果dx1==0: a2=数学。π/2 其他: a2=数学。:?/dx1) 如果(a2 & lt;0和底部。y比;top.y)/或(a2祝辞0和底部。y & lt;top.y)/: a2 +=math.pi b=a2 - a dx2=c * math.cos (b) dy2=c * sin (b) newTop=点(dx2 +底部。x, dy2 + bottom.y) 返回分支(底部,newTop,自我。分支,自我。等级+ 1) 类树(对象): def __init__(自我、根、帆布、底部,分支=3,深度=3): 自我。根=根 自我。帆布画布=自我。底=底部 自我。前=前 自我。分支=分支 self.depth=深度 self.new () def创(自我,n=1): 因为我在范围(n): self.getLeaves () 在self.leaves节点: node.nextGen () self.show () def新(自我): 自我。leavesCount=0 自我。分支=分支(自我。底,自我。前,self.branches) self.gen (self.depth) 打印”叶子数:% d % self.leavesCount def chgDepth(自我,d): self.depth +=d 如果self.depth & lt;0:self.depth=0 如果self.depth比;10:self.depth=10 self.new () def chgBranch(自我,d): 自我。+=d分支 如果自我。分支& lt;1:自我。分支=1 如果自我。分支机构在10:自我。分支=10 self.new () def getLeaves(自我): 自我。叶子=[] self.map (self.findLeaf) def findLeaf(自我、节点): 如果len (node.children)==0: self.leaves.append(节点) def显示(自我): 因为我在self.canvas.find_all (): self.canvas.delete(我) self.map (self.drawNode) self.canvas.tag_raise(“叶子”) def退出(自我,evt): sys.exit (0) def地图(自我,func=λ节点:节点): #遍历树 孩子=[self.branch] 虽然len(孩子)!=0: newChildren=[] 为节点的孩子: func(节点) newChildren.extend (node.children) 孩子=newChildren def drawNode(自我、节点): self.line2 ( # self.canvas.create_line ( node.bottom.x, node.bottom.y, node.top.x, node.top.y, 填补=" # 100 ", 宽=1.5 * * (self.depth - node.level), 标签="分支level_ % d % node.level, ) 如果len (node.children)==0: #画叶子 自我。leavesCount +=1 self.canvas.create_oval ( node.top。x - 3, node.top。y - 3, node.top。x + 3, node.top。y + 3, 填补=" # 090 ", 标签="叶", ) self.canvas.update () def么(自我,x0, y0, (x1, y1),宽度=1,填补=?00 #”,minDist=10,标签=" "): 点=压力(x0, y0 (x1, y1, minDist) dots2=[] 因为我在范围(len(点)- 1): dots2.extend([点[我]以下方式, 点[我].y, 点(i + 1)方式, 点(i + 1) .y]) self.canvas.create_line ( dots2, 填补=填补, 宽度=宽度, 光滑=True, 标签=标记, ) def压力(x0, y0 (x1, y1, d): 点=[] dx, dy, r=x1 - x0, y1 - y0, 0 如果dx !=0: r=(dy)/dx浮动 c=数学。√dx * * 2 + dy * * 2) n=int (c/d) + 1 因为我在范围(n): 如果dx !=0: x=dx *我/n y=x * r 其他: x=dx y=dy *我/n 如果我在0: x +=d * (0.5 - random.random ()) * 0.25 y +=d * (0.5 - random.random ()) * 0.25 x +=x0 y +=y0 点。追加(点(x, y)) 点。追加(点(x1, y1)) 返回点 if __name__==癬_main__”: 根=Tkinter.Tk () root.title(“树”) gw, gh=800, 600 帆布=Tkinter.Canvas(根, 宽度=gw, 身高=gh, ) canvas.pack () 树=树(根、帆布、点(千瓦/2,gh - 20),点(千瓦/2,gh * 0.2),/分支=2,深度=8) 根。bind (“n”,λevt: tree.new ()) 根。绑定(“=?λevt: tree.chgDepth (1)) 根。bind(“+”,λevt: tree.chgDepth (1)) 根。bind(“-”,λevt: tree.chgDepth (1)) 根。bind (“b”,λevt: tree.chgBranch (1)) 根。bind (“c”,λevt: tree.chgBranch (1)) 根。bind (q, tree.exit) root.mainloop ()Python如何生成树形图案