本文實(shí)例為大家分享了Python生成樹(shù)形圖案的具體代碼,供大家參考,具體內(nèi)容如下

先看一下效果,見(jiàn)下圖。

上面這顆大樹(shù)是使用Python + Tkinter繪制的,主要原理為使用分形畫(huà)樹(shù)干、樹(shù)枝,最終葉節(jié)點(diǎn)上畫(huà)上綠色圓圈代表樹(shù)葉。當(dāng)然,為了看起來(lái)更真實(shí),繪制過(guò)程中也加入了一些隨機(jī)變化,比如樹(shù)枝會(huì)稍微有些扭曲而不是一條直線,分叉的角度、長(zhǎng)短等都會(huì)隨機(jī)地作一些偏移等。
以下是完整源代碼:
# -*- coding: utf-8 -*-
import Tkinter
import sys, random, math
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return "<Point>: (%f, %f)" % (self.x, self.y)
class Branch(object):
def __init__(self, bottom, top, branches, level = 0):
self.bottom = bottom
self.top = top
self.level = level
self.branches = branches
self.children = []
def __str__(self):
s = "Top: %s, Bottom: %s, Children Count: %d" % /
(self.top, self.bottom, len(self.children))
return s
def nextGen(self, n = -1, rnd = 1):
if n <= 0: n = self.branches
if rnd == 1:
n = random.randint(n / 2, n * 2)
if n <= 0: n = 1
dx = self.top.x - self.bottom.x
dy = self.top.y - self.bottom.y
r = 0.20 + random.random() * 0.2
if 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
else:
x = dx * r
y = x * dy / dx
x += self.bottom.x
y += self.bottom.y
oldTop = self.top
self.top = Point(x, y)
a = math.pi / (2 * n)
for i in range(n):
a2 = -a * (n - 1) / 2 + a * i - math.pi
a2 *= 0.9 + random.random() * 0.2
self.children.append(self.mkNewBranch(self.top, oldTop, a2))
def mkNewBranch(self, bottom, top, a):
dx1 = top.x - bottom.x
dy1 = top.y - bottom.y
r = 0.9 + random.random() * 0.2
c = math.sqrt(dx1 ** 2 + dy1 ** 2) * r
if dx1 == 0:
a2 = math.pi / 2
else:
a2 = math.atan(dy1 / dx1)
if (a2 < 0 and bottom.y > top.y) /
or (a2 > 0 and bottom.y < top.y) /
:
a2 += math.pi
b = a2 - a
dx2 = c * math.cos(b)
dy2 = c * math.sin(b)
newTop = Point(dx2 + bottom.x, dy2 + bottom.y)
return Branch(bottom, newTop, self.branches, self.level + 1)
class Tree(object):
def __init__(self, root, canvas, bottom, top, branches = 3, depth = 3):
self.root = root
self.canvas = canvas
self.bottom = bottom
self.top = top
self.branches = branches
self.depth = depth
self.new()
def gen(self, n = 1):
for i in range(n):
self.getLeaves()
for node in self.leaves:
node.nextGen()
self.show()
def new(self):
self.leavesCount = 0
self.branch = Branch(self.bottom, self.top, self.branches)
self.gen(self.depth)
print "leaves count: %d" % self.leavesCount
def chgDepth(self, d):
self.depth += d
if self.depth < 0: self.depth = 0
if self.depth > 10: self.depth = 10
self.new()
def chgBranch(self, d):
self.branches += d
if self.branches < 1: self.branches = 1
if self.branches > 10: self.branches = 10
self.new()
def getLeaves(self):
self.leaves = []
self.map(self.findLeaf)
def findLeaf(self, node):
if len(node.children) == 0:
self.leaves.append(node)
def show(self):
for i in self.canvas.find_all():
self.canvas.delete(i)
self.map(self.drawNode)
self.canvas.tag_raise("leaf")
def exit(self, evt):
sys.exit(0)
def map(self, func = lambda node: node):
# 遍歷樹(shù)
children = [self.branch]
while len(children) != 0:
newChildren = []
for node in children:
func(node)
newChildren.extend(node.children)
children = newChildren
def drawNode(self, node):
self.line2(
# self.canvas.create_line(
node.bottom.x,
node.bottom.y,
node.top.x,
node.top.y,
fill = "#100",
width = 1.5 ** (self.depth - node.level),
tags = "branch level_%d" % node.level,
)
if len(node.children) == 0:
# 畫(huà)葉子
self.leavesCount += 1
self.canvas.create_oval(
node.top.x - 3,
node.top.y - 3,
node.top.x + 3,
node.top.y + 3,
fill = "#090",
tag = "leaf",
)
self.canvas.update()
def line2(self, x0, y0, x1, y1, width = 1, fill = "#000", minDist = 10, tags = ""):
dots = midDots(x0, y0, x1, y1, minDist)
dots2 = []
for i in range(len(dots) - 1):
dots2.extend([dots[i].x,
dots[i].y,
dots[i + 1].x,
dots[i + 1].y])
self.canvas.create_line(
dots2,
fill = fill,
width = width,
smooth = True,
tags = tags,
)
def midDots(x0, y0, x1, y1, d):
dots = []
dx, dy, r = x1 - x0, y1 - y0, 0
if dx != 0:
r = float(dy) / dx
c = math.sqrt(dx ** 2 + dy ** 2)
n = int(c / d) + 1
for i in range(n):
if dx != 0:
x = dx * i / n
y = x * r
else:
x = dx
y = dy * i / n
if i > 0:
x += d * (0.5 - random.random()) * 0.25
y += d * (0.5 - random.random()) * 0.25
x += x0
y += y0
dots.append(Point(x, y))
dots.append(Point(x1, y1))
return dots
if __name__ == "__main__":
root = Tkinter.Tk()
root.title("Tree")
gw, gh = 800, 600
canvas = Tkinter.Canvas(root,
width = gw,
height = gh,
)
canvas.pack()
tree = Tree(root, canvas, Point(gw / 2, gh - 20), Point(gw / 2, gh * 0.2), /
branches = 2, depth = 8)
root.bind("n", lambda evt: tree.new())
root.bind("=", lambda evt: tree.chgDepth(1))
root.bind("+", lambda evt: tree.chgDepth(1))
root.bind("-", lambda evt: tree.chgDepth(-1))
root.bind("b", lambda evt: tree.chgBranch(1))
root.bind("c", lambda evt: tree.chgBranch(-1))
root.bind("q", tree.exit)
root.mainloop() 另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性?xún)r(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專(zhuān)為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
網(wǎng)站標(biāo)題:Python如何生成樹(shù)形圖案-創(chuàng)新互聯(lián)
分享路徑:http://chinadenli.net/article6/digoog.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)、ChatGPT、網(wǎng)頁(yè)設(shè)計(jì)公司、建站公司、全網(wǎng)營(yíng)銷(xiāo)推廣、靜態(tài)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容