Canvas没有画点的函数,我们就用某一点到其右下相邻点的连线来代替。然后自定义一个函数Graph(),把给定函数f(x)在指定区间里的点 (x, f(x)) 依次画出,步进间隔小到一定程度就会连成f(x)对应的曲线。
for ... in range()的步进值只能是整数,所以引入numpy库的arange(),其步进可以是小数,例: for i in numpy.arange(0,2,0.01) # 表示区间[0,1)上步进0.01,共循环200次。
函数解析式的图像
import tkinter as tk import pyautogui as ag from math import * from numpy import arange as np def Window_Open(W, H): X, Y = ag.size() winSize = str(W)+"x"+str(H) winPos = winSize + "+" + str((X - W) // 2) winPos += "+" + str((Y - H) // 2) win.geometry(winPos) win.resizable(False, False) title = u'桌面分辨率:' + str(X) + "x" + str(Y) title += ' ' * 5 + u'窗体大小:' + winSize win.title(title) win.update() def Graph(func,x0,y0,xmin,xmax,w,h,c='blue',step=0.001): 'xmin,xmax 自变量的取值范围; c 图像颜色' 'x0,y0 原点坐标 w,h 横纵轴半长 step 步进' coord = x0-w,y0,x0+w,y0 tCanvas.create_line(coord,fill='black') coord = x0,y0-h,x0,y0+h tCanvas.create_line(coord,fill='black') w1,w2=100,120 # w1,w2为自变量和函数值在横纵轴上的放大倍数 for x in np(xmin,xmax+step,step): y = func(x) coord = x0+w1*x,y0-w2*y,x0+w1*x+1,y0-w2*y+1 if abs(x*w1)<w and abs(y*w2)<h: tCanvas.create_line(coord,fill=c) tCanvas.update() if __name__ == '__main__': win = tk.Tk() Window_Open(800,480) tCanvas = tk.Canvas(win, width=win.winfo_width(), height=480, bg='white') tCanvas.pack(side="top") x0,y0=400,240 # 原点坐标 xmax=pi*2 # 自变量最大值,超过横坐标最大值被截短 w,h=380,220 # 横纵轴的正向最大值 fx1 = lambda x : sin(x)+cos(x) fx2 = lambda x : sin(x)*cos(x) gx1 = lambda x : exp(abs(x/4))-2 gx2 = lambda x : (x/2)**3-2*(x/2)**2+x/2-1 Graph(sin,x0,y0,-xmax,xmax,w,h) Graph(cos,x0,y0,-xmax,xmax,w,h,'red') Graph(fx1,x0,y0,-xmax,xmax,w,h,'lime') Graph(fx2,x0,y0,-xmax,xmax,w,h,'orange') Graph(gx1,x0,y0,-xmax,xmax,w,h,'magenta') Graph(gx2,x0,y0,-xmax,xmax,w,h,'limegreen') win.mainloop()
效果图:
心形曲线参数方程的图像
把Graph()函数稍作改进,就能画出参数方程对应的曲线图像,如下例:心形曲线的图像
import tkinter as tk import pyautogui as ag from math import * from numpy import arange as np def Window_Open(W, H): X, Y = ag.size() winSize = str(W)+"x"+str(H) winPos = winSize + "+" + str((X - W) // 2) winPos += "+" + str((Y - H) // 2) win.geometry(winPos) win.resizable(False, False) title = u'桌面分辨率:' + str(X) + "x" + str(Y) title += ' ' * 5 + u'窗体大小:' + winSize win.title(title) win.update() def Graph(funcx,funcy,x0,y0,tmin,tmax,w,h,c='blue',step=0.001): 'xmin,xmax 自变量的取值范围; c 图像颜色' 'x0,y0 原点坐标 w,h 横纵轴半长 step 步进' coord = x0-w,y0,x0+w,y0 tCanvas.create_line(coord,fill='black') coord = x0,y0-h,x0,y0+h tCanvas.create_line(coord,fill='black') w1,w2=100,110 # w1,w2为自变量和函数值在横纵轴上的放大倍数 for t in np(tmin,tmax+step,step): x = funcx(t) y = funcy(t) coord = x0+w1*x,y0-w2*y,x0+w1*x+1,y0-w2*y+1 if abs(x*w1)<w and abs(y*w2)<h: tCanvas.create_line(coord,fill=c) tCanvas.update() if __name__ == '__main__': win = tk.Tk() Window_Open(480,480) tCanvas = tk.Canvas(win, width=win.winfo_width(), height=480, bg='white') tCanvas.pack(side="top") x0,y0=240,240 # 原点坐标 a = 0.7 fx = lambda t : a*(2.0*sin(t)-sin(2*t)) fy = lambda t : a*(1.6*cos(t)-cos(2*t))+0.5 Graph(fx,fy,x0,y0,-pi,pi,220,200,c='red') win.mainloop()
效果图:
椭圆、双曲线、抛物线的图像
import tkinter as tk import pyautogui as ag from math import * from numpy import arange as np def Window_Open(W, H): X, Y = ag.size() winSize = str(W)+"x"+str(H) winPos = winSize + "+" + str((X - W) // 2) winPos += "+" + str((Y - H) // 2) win.geometry(winPos) win.resizable(False, False) title = u'桌面分辨率:' + str(X) + "x" + str(Y) title += ' ' * 5 + u'窗体大小:' + winSize win.title(title) win.update() def Graph(funcx,funcy,x0,y0,tmin,tmax,w,h,c='blue',step=0.001): 'xmin,xmax 自变量的取值范围; c 图像颜色' 'x0,y0 原点坐标 w,h 横纵轴半长 step 步进' coord = x0-w,y0,x0+w,y0 tCanvas.create_line(coord,fill='black') coord = x0,y0-h,x0,y0+h tCanvas.create_line(coord,fill='black') w1,w2=100,100 # w1,w2为自变量和函数值在横纵轴上的放大倍数 for t in np(tmin,tmax+step,step): x = funcx(t) y = funcy(t) coord = x0+w1*x,y0-w2*y,x0+w1*x+1,y0-w2*y+1 if abs(x*w1)<w and abs(y*w2)<h: tCanvas.create_line(coord,fill=c) tCanvas.update() if __name__ == '__main__': win = tk.Tk() Window_Open(480,480) tCanvas = tk.Canvas(win, width=win.winfo_width(), height=480, bg='white') tCanvas.pack(side="top") x0,y0=240,240 a,b = 1,1.2 p = 0.5 f1x = lambda t : a*cos(t) f1y = lambda t : b*sin(t) f2x = lambda t : a/cos(t) f2y = lambda t : b*tan(t) f3x = lambda t : 2*p*t**2 f3y = lambda t : 2*p*t Graph(f1x,f1y,x0,y0,-pi,pi,220,200) Graph(f2x,f2y,x0,y0,-pi,pi,220,200,c='red') Graph(f3x,f3y,x0,y0,-pi,pi,220,200,c='green') win.mainloop()
效果图:
附:圆锥曲线的参数方程
椭圆
x = a*cost
y = b*sint
双曲线
x = a*sect
y = b*tant
抛物线
x = 2*p*t²
y = 2*p*t