Python中tkinter模块创建画布实现函数图像的功能

本文介绍了一位非计算机专业的学生如何使用Python的tkinter库,结合数学的正弦函数,实现了一个可缩放、移动的动态函数图像绘制程序。通过修改全局变量,实现了坐标轴的调整和函数图像的精度控制,展示了基础的图形用户界面编程技巧。
摘要由CSDN通过智能技术生成

非计算机专业准备备考二级,然后今天刚学到tkinter.canvas模块,看到书中的正弦函数绘制,在基础上进行改进,通过改变全局的一些初始变量实现了函数图像的放大缩小,位置移动等功能。在这里做个保存!

参考教材 - Python程序设计基础(第二版)李东方  (ISBN:978 7121 376054)  [例9-6]

import math
import tkinter

# 增加了设置画布大小,设置坐标位置,设置x, y比例长度, 设置图像精度以及设置绘制的函数

canvas_x = 320  # 画布x轴像素长度
canvas_y = 240  # 画布y轴像素长度
origin = (10, 120)  # 原点的x, y像素值 - 原点中心值为(160, 120)
unit_length_x = 20  # 坐标轴中x的比例长度
unit_length_y = 40  # 坐标轴中y的比例长度
curve_precision = 0.01  # 曲线的画图精度,可以理解为Δx - 经过测试,一般0.01即可
fun_text = 'y=sin(x)'  # 绘制的函数

coordinate_x = origin[1]  # 坐标轴 x (在y轴上的)的位置
coordinate_y = origin[0]  # 坐标轴 y (在x轴上的)的位置

def calc_x(t):
    # 通过传入的数据为坐标轴的位置,因此进行一个坐标轴 - 像素点转换,然后返回
    num_x = t * unit_length_x
        # num_x += canvas_x/2
    # 由于坐标轴位置变化,所以对应的也要变化
    num_x += coordinate_y
    return num_x


def calc_y(t):
    # 通过数学计算计算出对应的y值,然后进行坐标轴 - 像素点转换
    num_y = math.sin(t) * unit_length_y  # 先放大
    # 由于y轴与x轴不同,y轴的正坐标方向与像素的正坐标方向是相反的
    # 所以首先将其翻转一下,然后在向下平移
    num_y = -num_y
        # num_y += canvas_y / 2
    # 由于坐标轴位置变化,所以对应的也要变化
    num_y += coordinate_x
    return num_y


if __name__ == '__main__':
    root = tkinter.Tk()

    mycanvas = tkinter.Canvas(root, width=canvas_x, height=canvas_y)
    mycanvas.pack()
    # 绘制坐标轴横线
            # mycanvas.create_line(0, canvas_y/2, canvas_x, canvas_y/2, fill='red', arrow=tkinter.LAST)
            # mycanvas.create_line(canvas_x/2, canvas_y, canvas_x/2, 0, fill='red', arrow=tkinter.LAST)
    # 由于改变了坐标轴位置,所以坐标轴也要改变
    mycanvas.create_line(0, coordinate_x, canvas_x, coordinate_x, fill='red', arrow=tkinter.LAST)
    mycanvas.create_line(coordinate_y, canvas_y, coordinate_y, 0, fill='red', arrow=tkinter.LAST)
    # 绘制坐标轴刻度
    # range(a, b)的计算方法:
                # # 首先明确 a 和 b 代表的是坐标轴的刻度
                # # 其次总长度为 x=320, y=240
                # # 由于40为一个单位,所以x轴可以分为320/40 = 8份,也就是7个坐标轴。y轴可以分为240/40=6份也就是5个坐标轴
                # # 因此x轴坐标刻度为[-8/2+1, 8/2),y轴坐标刻度为[-6/2+1, 6/2)
                # # x:range( (-canvas_x/unit_length_x) / 2 + 1, (canvas_x/unit_length_x) / 2)
                # # x:range( (-canvas_y/unit_length_y) / 2 + 1, (canvas_y/unit_length_y) / 2)
                #
                # for i in range( math.ceil((-canvas_x/unit_length_x) / 2) + 1, math.ceil((canvas_x/unit_length_x) / 2)):
                #     # 由于计算出来的 i 并不是实际画布像素值,所以要乘上unit_length_x
                #     j = i*unit_length_x  # 坐标轴放大40倍
                #     # 对于 i*unit_length_x即是获得了实际的坐标轴对应的放大40倍后的值,但是这个值并不是真正的像素点
                #     # 由于我们是以中心点(canvas/x, canvas_y)为原点的,因此我们要在这里加上对应的原点像素值才能得到真正的坐标轴对应的像素点
                #     mycanvas.create_line(j+canvas_x/2, canvas_y/2, j+canvas_x/2, canvas_y/2-5, fill='red')
                #     mycanvas.create_text(j+canvas_x/2, canvas_y/2+10, text=i)
                # for i in range( math.ceil((-canvas_y/unit_length_y) / 2) + 1, math.ceil((canvas_y/unit_length_y) / 2)):
                #     j = i*unit_length_y  # 坐标轴放大40倍
                #     mycanvas.create_line(canvas_x/2, j+canvas_y/2, canvas_x/2+5, j+canvas_y/2, fill='red')
                #     mycanvas.create_text(canvas_x/2-10, j+canvas_y/2, text=-i)

    # 因为增加了坐标轴的位置,因此上述理论推翻
    # 首先明确,x轴的轴正坐标像素长度应该为:canvas_x - coordinate_y
    # 因此负半轴像素值为:canvas_x - (canvas_x - cordinate_y)也就是cordinate_y
    # 此处的算法应该改为range*( -(coordinate_y / unit_length_x) + 1, ((canvas_x-coordinate_y) / unit_length_x)) )
    for i in range( -math.ceil((coordinate_y / unit_length_x)) + 1, math.ceil((canvas_x-coordinate_y) / unit_length_x)):
        print(i)
        j = i*unit_length_x
        # 对于 i*unit_length_x即是获得了实际的坐标轴对应的放大unit_length倍后的值,但是这个值并不是真正的像素点
        # 由于我们是以中心点(coordinate_y, coordinate_x)为原点的,因此我们要在这里加上对应的原点像素值才能得到真正的坐标轴对应的像素点
        mycanvas.create_line(j+coordinate_y, coordinate_x, j+coordinate_y, coordinate_x-5, fill='red')
        mycanvas.create_text(j+coordinate_y, coordinate_x+10, text=i)
    # 同理由于y轴是相反的,所以正半轴为:cordinate_x,负半轴为canvas_y - cordinate_x
    # 此处的算法应该改为range*( -(canvas_y - coordinate_x) / unit_length_y) + 1, (cordinate_x / unit_length_y)) )
    for i in range( -math.ceil((canvas_y - coordinate_x) / unit_length_y) + 1, math.ceil((coordinate_x / unit_length_y))):
        print(i)
        j = i*unit_length_y
        # 对于 i*unit_length_y即是获得了实际的坐标轴对应的放大unit_length倍后的值,但是这个值并不是真正的像素点
        # 由于我们是以中心点(coordinate_y, coordinate_x)为原点的,因此我们要在这里加上对应的原点像素值才能得到真正的坐标轴对应的像素点
        mycanvas.create_line(coordinate_y, j+coordinate_x, coordinate_y+5, j+coordinate_x, fill='red')
        mycanvas.create_text(coordinate_y-10, j+coordinate_x, text=i)


    # 绘制函数名称 - 位置在y轴右上方
    mycanvas.create_text(coordinate_y + 50, 10, text=fun_text)

    # 此处的-3是坐标轴的最低值,3是坐标轴的最大值
    # 此处我们仅将坐标轴的值传入函数,然后通过函数输出一个对应的像素值
    # 通过改变坐标轴的值(从坐标轴的最小值一直到坐标轴的最大值,每次增加curve_precision)
            # draw_point = math.ceil((-canvas_x/unit_length_x) / 2) + 1
            # while draw_point < math.ceil((canvas_x/unit_length_x) / 2) - 1:
    # 由于坐标轴位置改变,所以对应的值要改变
    draw_point = -math.ceil((coordinate_y / unit_length_x)) + 1  # 此处为x轴负半轴
    while draw_point < math.ceil((canvas_x-coordinate_y)) - 1:  # 此处为x轴正半轴
        mycanvas.create_line(calc_x(draw_point), calc_y(draw_point), calc_x(draw_point+0.01), calc_y(draw_point+0.01), fill='blue')
        draw_point += curve_precision

    root.mainloop()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值