继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

一个基于 Python 的图形通用库

心之宙
关注TA
已关注
手记 71
粉丝 35
获赞 167

graph-tensor 是一个基于 Python 的图形通用库,该库于今天刚刚开发,功能比较单一,后续会不断添加新的功能进去。

graph-tensor已经被放置在了PyPI,可以直接在https://pypi.org/project/graph-tensor/ 中直接下载使用。下面简单的介绍本库的设计的起点或者说是设计思路。

1. 设计的基础

一般地,在数学中使用一个向量 x=(x0,x1,⋯,xn−1)∈Rnx=(x_0,x_1,\cdots,x_{n-1}) \in \mathbb{R}^nx=(x0,x1,,xn1)Rn 来描述空间中的一个(即●);使用向量的减法表示一个有向线段 c=a−bc = a - bc=ab,即 ccc 是由点 bbb 指向点 aaa 的有向线段(这里并不严谨)。考虑到计算机的离散特性,我们很难获取连续的“点”,故而,我们转向使用小方块 ■ 表示“点”(即图像的像素点)。这些 ■ 以不同的方式进行组合排列出不同的图案,比如线段、矩形框、椭圆、圆锥等。

我们先研究二维平面的点。

2. 画布:Canvas

这些点总是需要一个“承载”容器,在数学中,一般称其为坐标系或者参考系。笛卡尔坐标系为大家所熟知,在三维空间中一般被分为左手系和右手系。由于本项目讨论的坐标系是基于 tkinter 的 Canvas 模块,而 Canvas 的坐标系可以看作是左手系的二维版本,即:水平向右表示 xxx 轴的正方向,竖直向下表示 yyy 轴的正方向。

因为“点动成线,线动成面,面动成体”,所以我们可以使用■在 Canvas 画出各种各样的二维图像元素。

为了定制统一化的图形元素,我们指定有向线段 direction=(x0,y0,x1,y1)\text{direction}=(x_0,y_0,x_1,y_1)direction=(x0,y0,x1,y1) 为全部图形元素的基本属性,其中 (x0,y0)(x_0,y_0)(x0,y0) 表示起点,(x1,y1)(x_1,y_1)(x1,y1) 表示终点。

可以运行如下代码看几个常见的图形元素:

from graph_tensor.graph.atom import Meta

def test_meta(direction = (20, 20, 220, 300)):
    from tkinter import Tk
    root = Tk()
    self = Meta(root, line_width=10, width=250, height=400, background='white')
    self.draw_graph(direction, 'Rectangle', 'blue')
    self.draw_graph(direction, 'Oval', 'red')
    self.draw_graph(direction, 'Arc', 'green', 'pieslice')
    self.draw_graph(direction, 'Line', 'black')
    self.layout()
    root.mainloop()

test_meta()

显示的效果见图1:

图1 常见的图形元素

图1 显示了红色的椭圆、绿色的扇形、蓝色的矩形、黑色的线段。从图中可以观察到给定相同的 direction,画出的图形元素有着相同的中心。从本质上讲,direction 可以看作是椭圆、扇形、矩形以及线段的方向向量。只要给定 direction,那么它们之间的关系就被牢牢的锁定了。

这里的 Meta 没有直接提供画“多边形”的方法,其实画“多边形”可以由画“线段”组合得到。下面给出代码实现:

from tkinter import Tk

def point2polygon(points):
    '''将点列转换为首尾相接的线段'''
    directions = []
    for start, end in zip(points, points[1:]):
        directions.append((*start, *end))
    directions.append((*points[-1], *points[0]))
    return directions

def draw_polygon(meta, *directions):
    '''画出多边形'''
    for direct in directions:
        meta.draw_graph(direct, 'Line', 'black', fill='red')

root = Tk()
self = Meta(root, line_width=5, width=250, height=400, background='white')

points = [
    (20, 20), (30, 50), (100, 250),
    (250, 340), (220, 230)
]
directions = point2polygon(points)
draw_polygon(self, *directions)
self.layout()
root.mainloop()

效果图见图2:

图2 画出多边形

您也可以使用 self.create_polygon(points, fill='red') 画出有内部填充的多边形。下面以“矩形”为例来说明这些图形元素的更多方法。

2.1 画虚线

可以使用如下代码画出虚线图形(需要指定参数 dash):

def test_meta_dash(direction = (20, 20, 220, 300)):
    from tkinter import Tk
    root = Tk()
    self = Meta(root, line_width=10, width=250, height=400, background='white')
    self.draw_graph(direction, 'Rectangle', 'blue', dash=5)
    self.layout()
    root.mainloop()

test_meta_dash()

效果见图3:

图3 Meta 画虚线的示例

6 绑定鼠标作画

可以直接使用选择器器与鼠标进行图形的绘制:

def drawing_trajectory():
    from graph_tensor.graph.atom import Meta
    from graph_tensor.graph.creator import Selector
    root = Tk()
    icon_meta = Meta(root, width=210, height=60)
    selector = Selector(icon_meta)

    meta = TrajectoryDrawing(root, selector=selector, background='white')

    # Makes the master widget change as the canvas size
    root.columnconfigure(0, weight=1)
    root.rowconfigure(0, weight=1)
    meta.layout()
    icon_meta.layout(0, 1)
    root.mainloop()


def drawing():
    from graph_tensor.graph.atom import Meta
    from graph_tensor.graph.creator import Selector
    root = Tk()
    icon_meta = Meta(root, width=210, height=60)
    selector = Selector(icon_meta)

    meta = Graph(root, selector=selector, background='white')
    # Makes the master widget change as the canvas size
    root.columnconfigure(0, weight=1)
    root.rowconfigure(0, weight=1)
    meta.layout()
    icon_meta.layout(0, 1)
    root.mainloop()

效果图见:

图4  使用鼠标作画

图5 自定义“抽象画”
更多的精彩内容请查阅 TensorAtom / tutorial7 tkinter 自定义画图工具

打开App,阅读手记
2人推荐
发表评论
随时随地看视频慕课网APP

相关阅读

线段树入门