用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字
云代码 - python代码库

新手练手代码

2021-10-17 作者: 陈同学举报

[python]代码库

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):
        # 遍历树
        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:
            # 画叶子
            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()


网友评论    (发表评论)


发表评论:

评论须知:

  • 1、评论每次加2分,每天上限为30;
  • 2、请文明用语,共同创建干净的技术交流环境;
  • 3、若被发现提交非法信息,评论将会被删除,并且给予扣分处理,严重者给予封号处理;
  • 4、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

输入口令后可复制整站源码

加载中,请稍后...