|
|
import random
|
|
|
import math
|
|
|
import numpy as np
|
|
|
import tkinter as tk
|
|
|
from math import *
|
|
|
from tkinter import *
|
|
|
from tkinter import messagebox
|
|
|
import matplotlib.pyplot as plt
|
|
|
import numpy.ma
|
|
|
import pyautogui as ag
|
|
|
from numpy import arange
|
|
|
|
|
|
|
|
|
def leftclick(event): # 测试鼠标点击
|
|
|
x, y = event.x, event.y
|
|
|
print('坐标{}, {}'.format(x, y))
|
|
|
|
|
|
|
|
|
def window_open(width, height):
|
|
|
X, Y = ag.size() # 获取分辨率
|
|
|
winSize = str(width) + "x" + str(height)
|
|
|
# print("winsize",winSize)
|
|
|
wiarangeos = winSize + "+" + str((X - width) // 2)
|
|
|
wiarangeos += "+" + str((Y - height) // 2)
|
|
|
# print("wiarangeos",wiarangeos)
|
|
|
# window.geometry(wiarangeos) #指定窗口大小
|
|
|
# window.resizable(False, False) #窗口不可调
|
|
|
title = u'桌面分辨率:' + str(X) + "x" + str(Y)
|
|
|
title += ' ' * 5 + u'窗体大小:' + winSize
|
|
|
window.title(title)
|
|
|
# window.update()
|
|
|
|
|
|
|
|
|
def x1_1(): # 随机给出1000个点坐标,赋值给xyMap,<class 'numpy.ndarray'>
|
|
|
shape = [1000, 2]
|
|
|
xyMap = np.random.randint(-200, 200, size=shape)
|
|
|
return xyMap
|
|
|
|
|
|
print(x1_1())
|
|
|
|
|
|
|
|
|
# ab = x1_1()
|
|
|
# print(ab,len(ab),type(ab))
|
|
|
|
|
|
def x1_2(problemIndex): # 程序给出任一函数 y=f(x)计算x=1到1000的y值,赋值给xyMap
|
|
|
# shape = [1000,2] #x值为1到1000,y为其对应函数值
|
|
|
xyMap = np.random.rand(1000, 2)
|
|
|
if problemIndex == 1:
|
|
|
for x in range(1, 1001):
|
|
|
xyMap[x - 1][0] = x # xyMap序号为0-999
|
|
|
xyMap[x - 1][1] = np.sin(x)
|
|
|
return xyMap
|
|
|
elif problemIndex == 2:
|
|
|
for x in range(1, 1001):
|
|
|
xyMap[x - 1][0] = x
|
|
|
xyMap[x - 1][1] = np.cos(x)
|
|
|
return xyMap
|
|
|
elif problemIndex == 3:
|
|
|
for x in range(1, 1001):
|
|
|
xyMap[x - 1][0] = x
|
|
|
xyMap[x - 1][1] = np.tan(x)
|
|
|
return xyMap
|
|
|
elif problemIndex == 4:
|
|
|
for x in range(1, 1001):
|
|
|
xyMap[x - 1][0] = x
|
|
|
xyMap[x - 1][1] = x * 2 + 2
|
|
|
return xyMap
|
|
|
|
|
|
|
|
|
print(x1_2(4)[:50])
|
|
|
print(x1_2(1))
|
|
|
|
|
|
def x1_3(problemIndex): # 程序给出任一函数y=f(x)计算x=-500到+500的y值赋值给xyMap
|
|
|
c = 0 # 此处x赋值为-500到-1到,1到500到1000个
|
|
|
shape = [1000, 2] # y赋值为其对应的函数
|
|
|
xyMap = np.random.rand(1000, 2)
|
|
|
if problemIndex == 1:
|
|
|
for x in range(-500, 500):
|
|
|
if (x == 0):
|
|
|
continue
|
|
|
xyMap[c][0] = x
|
|
|
xyMap[c][1] = math.sin(x)
|
|
|
c += 1
|
|
|
return xyMap
|
|
|
elif problemIndex == 2:
|
|
|
for x in range(-500, 500):
|
|
|
if (x == 0):
|
|
|
continue
|
|
|
xyMap[c][0] = x
|
|
|
xyMap[c][1] = math.cos(x)
|
|
|
c += 1
|
|
|
return xyMap
|
|
|
elif problemIndex == 3:
|
|
|
for x in range(-500, 500):
|
|
|
if (x == 0):
|
|
|
continue
|
|
|
xyMap[c][0] = x
|
|
|
xyMap[c][1] = math.tan(x)
|
|
|
c += 1
|
|
|
return xyMap
|
|
|
elif problemIndex == 4:
|
|
|
for x in range(-500, 501):
|
|
|
if (x == 0):
|
|
|
continue
|
|
|
xyMap[c][0] = x
|
|
|
xyMap[c][1] = x * 2 + 2
|
|
|
c += 1
|
|
|
return xyMap
|
|
|
|
|
|
|
|
|
# print(x1_3(1))
|
|
|
|
|
|
def x1_4(ProblemIndex):
|
|
|
step = 3 # 步长
|
|
|
y = []
|
|
|
i, c = 0, 0
|
|
|
number = 1000 # 个数
|
|
|
while (True):
|
|
|
if (c == number):
|
|
|
break
|
|
|
else:
|
|
|
y.append(i)
|
|
|
i += step
|
|
|
c += 1
|
|
|
y = np.array(y)
|
|
|
xyMap = np.random.rand(1000, 2)
|
|
|
|
|
|
if (ProblemIndex == 1):
|
|
|
for i in range(len(y)):
|
|
|
xyMap[i][0] = y[i]
|
|
|
xyMap[i][1] = 2 * y[i] + 1
|
|
|
return xyMap
|
|
|
elif (ProblemIndex == 2):
|
|
|
for i in range(len(y)):
|
|
|
xyMap[i][0] = y[i]
|
|
|
xyMap[i][1] = y[i] / 3
|
|
|
return xyMap
|
|
|
|
|
|
|
|
|
def x_6(xymap): # 按xymap绘制曲线
|
|
|
xy = xymap.tolist()
|
|
|
canvas.create_line(xy, fill="purple", width=1)
|
|
|
|
|
|
|
|
|
def x_5(x, y):
|
|
|
# 1----x,y轴
|
|
|
canvas.create_line(0, y / 2, x, y / 2, fill='white', arrow=LAST) # 绘制x轴
|
|
|
canvas.create_line(x / 2, 0, x / 2, y, fill='white', arrow=FIRST) # 绘制y轴
|
|
|
|
|
|
|
|
|
# 绘制坐标轴的刻度
|
|
|
def kedu():
|
|
|
# #两个for分别为xy刻度
|
|
|
for i in range(-math.ceil((loca_y / bili_x)) + 1, math.ceil((canvas_x - loca_y) / bili_x)):
|
|
|
j = i * bili_x
|
|
|
# i*bili_x即实际的坐标轴对应的放大bili倍后的值,但是这个值并不是真正的像素点
|
|
|
# 以中心点(loca_y, loca_x)为原点的,要在这里加上对应的原点像素值才能得到真正的坐标轴对应的像素点
|
|
|
if (i % 10 == 0):
|
|
|
canvas.create_line(j + loca_y, loca_x, j + loca_y, loca_x - 5, fill='black')
|
|
|
canvas.create_text(j + loca_y, loca_x + 10, text=i)
|
|
|
# y轴是相反的,所以正半轴为:cordinate_x,负半轴为canvas_y - cordinate_x
|
|
|
# 此处的算法应该改为range*( -(canvas_y - loca_x) / bili_y) + 1, (cordinate_x / bili_y)) )
|
|
|
# xmin,xmax =math.ceil((loca_y / bili_x)) + 1, math.ceil((canvas_x-loca_y) / bili_x)
|
|
|
# print(xmin,xmax)
|
|
|
|
|
|
for i in range(-math.ceil((canvas_y - loca_x) / bili_y) + 1, math.ceil((loca_x / bili_y))):
|
|
|
j = -(i * bili_y)
|
|
|
# i*bili_y即实际的坐标轴对应的放大bili倍后的值,但是这个值并不是真正的像素点
|
|
|
# 以中心点(loca_y, loca_x)为原点的,因此在这里加上对应的原点像素值才能得到真正的坐标轴对应的像素点
|
|
|
if (i == 0):
|
|
|
continue
|
|
|
elif (i % 2 == 0):
|
|
|
canvas.create_line(loca_y, j + loca_x, loca_y + 5, j + loca_x, fill='black')
|
|
|
canvas.create_text(loca_y - 10, j + loca_x, text=i)
|
|
|
# print(loca_x,loca_y)
|
|
|
|
|
|
|
|
|
def si():
|
|
|
global x0, y0, loca_x, loca_y
|
|
|
x0, y0 = 375, 275 # 四象限原点坐标
|
|
|
loca_x, loca_y = y0, x0
|
|
|
canvas.create_rectangle(0, 0, x_zhou, y_zhou, fill='#CDCDCD', width=5, outline='#CDCDCD')
|
|
|
|
|
|
canvas.create_oval(170, y_zhou + 145, 200, y_zhou + 175, fill='black', width=1, outline='white')
|
|
|
canvas.create_oval(350, y_zhou + 145, 380, y_zhou + 175, fill='white', width=1, outline='black')
|
|
|
# kedu()
|
|
|
canvas.create_line(0, y0, x_zhou, y0, fill='white', arrow=LAST) # 一象限xy轴
|
|
|
canvas.create_line(x0, 0, x0, y_zhou, fill='white', arrow=FIRST)
|
|
|
|
|
|
|
|
|
def yi():
|
|
|
global x0, y0, loca_x, loca_y
|
|
|
x0, y0 = 20, 500 # 一象限原点
|
|
|
loca_x, loca_y = y0, x0
|
|
|
canvas.create_rectangle(0, 0, x_zhou, y_zhou, fill='#CDCDCD', width=5, outline='#CDCDCD')
|
|
|
|
|
|
canvas.create_oval(170, y_zhou + 145, 200, y_zhou + 175, fill='white', width=1, outline='black')
|
|
|
canvas.create_oval(350, y_zhou + 145, 380, y_zhou + 175, fill='black', width=1, outline='white')
|
|
|
# kedu()
|
|
|
canvas.create_line(0, y0, x_zhou, y0, fill='white', arrow=LAST) # 一象限xy轴
|
|
|
canvas.create_line(x0, 0, x0, y_zhou, fill='white', arrow=FIRST)
|
|
|
|
|
|
|
|
|
def x_show(x, y): # GUI界面 坐标系的x:x轴长,y:y轴长
|
|
|
xmin, xmax = math.ceil((loca_y / bili_x)) + 1, math.ceil((canvas_x - loca_y) / bili_x)
|
|
|
# print("xmain",xmin,xmax)
|
|
|
# 1----x,y轴
|
|
|
# canvas.create_line(0,y0,x,y0,fill='white',arrow=LAST) # 一象限xy轴
|
|
|
# canvas.create_line(x0,0,x0,y,fill='white',arrow=FIRST)
|
|
|
|
|
|
# 2----背景涂白
|
|
|
canvas.create_rectangle(x, 0, 1200, y, fill='white', width=5, outline='white') # 右上区白色背景
|
|
|
canvas.create_rectangle(0, y, 1200, 800, fill='white', width=3, outline='white') # 下半区白色背景
|
|
|
|
|
|
# 3----输入框
|
|
|
e1 = tk.Entry(window, font=('Arial', 18), width=40, bg='#C0D9D9', bd=1) # 用户自命名函数输入
|
|
|
e1.place(x=70, y=y + 15, height=50)
|
|
|
canvas.create_text(95, y + 100, text="x步长", fill='black', font=("Purisa", 15, "bold"))
|
|
|
e2 = tk.Entry(window, font=('Arial', 15), width=15, bg='#C0D9D9', bd=1) # x步长输入
|
|
|
e2.place(x=130, y=y + 75, height=50)
|
|
|
canvas.create_text(380, y + 100, text="x个数", fill='black', font=("Purisa", 15, "bold"))
|
|
|
e3 = tk.Entry(window, font=('Arial', 15), width=15, bg='#C0D9D9', bd=1) # x个数输入
|
|
|
e3.place(x=415, y=y + 75, height=50)
|
|
|
|
|
|
e4 = tk.Entry(window, font=('Arial', 18), width=10, bg='#C0D9D9', bd=1) # x放大倍数
|
|
|
e4.place(x=200, y=750, height=35)
|
|
|
canvas.create_text(95, y + 100, text="x步长", fill='black', font=("Purisa", 15, "bold"))
|
|
|
e5 = tk.Entry(window, font=('Arial', 15), width=10, bg='#C0D9D9', bd=1) # y放大倍数
|
|
|
e5.place(x=580, y=750, height=35)
|
|
|
|
|
|
# 4----右侧label文本
|
|
|
canvas.create_text(x + 180, 35, text='可识别基本函数', fill='red', font=("Purisa", 25, "bold"))
|
|
|
text = "可支持下列函数的加减乘除组合运算\n" \
|
|
|
"y=sin(x)\n" \
|
|
|
"y=cos(x)\n" \
|
|
|
"y=tan(x)\n" \
|
|
|
"y=cot(x)\n" \
|
|
|
"y=x^n\n" \
|
|
|
"y=P1(y=x^3+x^2+x+5)\n" \
|
|
|
"---将括号内的表达式命名为P1,P1可\n" \
|
|
|
"出现于用户构造中"
|
|
|
label = tk.Label(window, text=text, font=('Arial', 15, 'bold italic'), bg='white',
|
|
|
# 设置标签内容区?
|
|
|
width=28, height=16,
|
|
|
# 设置填充区距离、边框宽度和其样式(凹陷式)
|
|
|
padx=5, pady=5, borderwidth=5, relief="sunken", justify="center")
|
|
|
label.place(x=x + 5, y=60)
|
|
|
|
|
|
# 5----左下按钮
|
|
|
canvas.create_text(100, y + 160, text="坐标轴", fill='black', font=("Purisa", 18, "bold"))
|
|
|
canvas.create_text(120, y + 210, text="x放大倍数", fill='black', font=("Purisa", 18, "bold"))
|
|
|
canvas.create_text(500, y + 210, text="y放大倍数", fill='black', font=("Purisa", 18, "bold"))
|
|
|
canvas.create_oval(170, y + 145, 200, y + 175, fill='white', width=1, outline='black') # 左小圆
|
|
|
canvas.create_oval(350, y + 145, 380, y + 175, fill='white', width=1, outline='black') # 右小圆
|
|
|
|
|
|
def function_user():
|
|
|
if (e1.get() == "y=sin(x)"):
|
|
|
Graph(0, sin, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#32CD32')
|
|
|
elif (e1.get() == "y=cos(x)"):
|
|
|
Graph(0, fx2, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#238E23')
|
|
|
elif (e1.get() == "y=tan(x)"):
|
|
|
Graph(0, fx3, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#FF6EC7')
|
|
|
elif (e1.get() == "y=cot(x)"):
|
|
|
Graph(0, fx4, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#CFB53B')
|
|
|
elif (e1.get() == "y=sin(x)+cos(x)"):
|
|
|
Graph(0, fx5, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#99CC32')
|
|
|
elif (e1.get() == "y=sin(x)*cos(x)"):
|
|
|
Graph(0, fx6, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#007FFF')
|
|
|
elif (e1.get() == "y=sin(x)-cos(x)+tan(x)"):
|
|
|
Graph(0, fx7, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#007FFF')
|
|
|
elif (e1.get() == "y=x"):
|
|
|
Graph(0, fx8, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#8E2323')
|
|
|
elif (e1.get() == "y=x**2"):
|
|
|
Graph(0, fx9, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#8E2323')
|
|
|
|
|
|
def function_print():
|
|
|
global bili_x, bili_y
|
|
|
bili_x = float(e4.get())
|
|
|
bili_y = float(e5.get())
|
|
|
buchang = float(e2.get())
|
|
|
kedu()
|
|
|
if (e1.get() == "y=sin(x)"):
|
|
|
Graph(buchang, sin, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#32CD32')
|
|
|
elif (e1.get() == "y=cos(x)"):
|
|
|
Graph(buchang, fx2, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#238E23')
|
|
|
elif (e1.get() == "y=tan(x)"):
|
|
|
Graph(buchang, fx3, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#FF6EC7')
|
|
|
elif (e1.get() == "y=cot(x)"):
|
|
|
Graph(buchang, fx4, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#CFB53B')
|
|
|
elif (e1.get() == "y=sin(x)+cos(x)"):
|
|
|
Graph(buchang, fx5, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#99CC32')
|
|
|
elif (e1.get() == "y=sin(x)*cos(x)"):
|
|
|
Graph(buchang, fx6, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#007FFF')
|
|
|
elif (e1.get() == "y=sin(x)-cos(x)+tan(x)"):
|
|
|
Graph(buchang, fx7, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#007FFF')
|
|
|
elif (e1.get() == "y=x"):
|
|
|
Graph(buchang, fx8, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#8E2323')
|
|
|
elif (e1.get() == "y=x**2"):
|
|
|
Graph(buchang, fx9, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#8E2323')
|
|
|
|
|
|
# 按钮一:命名函数
|
|
|
button = tk.Button(window, text='用户命名并新增基本函数', bg='#38B0DE', command=function_user,
|
|
|
font=("Purisa", 13, "bold"), foreground='black')
|
|
|
button.place(x=x + 8, y=y + 10, width=440, height=60)
|
|
|
# 按钮二:输出
|
|
|
button = tk.Button(window, text='输出', font=("Purisa", 13, "bold"), command=function_print, foreground='black')
|
|
|
button.place(x=x + 10, y=y + 90, width=70, height=60)
|
|
|
# 按钮三:切换四象限
|
|
|
button = tk.Button(window, command=si, text='四象限', bd=0, font=("Asria", 15, "bold"))
|
|
|
button.place(x=230, y=y + 140, width=70, height=45)
|
|
|
# 按钮四:切换一象限
|
|
|
button = tk.Button(window, command=yi, text='一象限', bd=0, font=("Asria", 15, "bold"))
|
|
|
button.place(x=400, y=y + 140, width=70, height=45)
|
|
|
|
|
|
|
|
|
def Graph(draw_precision, func, x0, y0, xmin, xmax, w, h, c='blue'): # 画基本函数图像
|
|
|
'xmin,xmax 自变量的取值范围; c 图像颜色'
|
|
|
'x0,y0 原点坐标 w,h 横纵轴半长 draw_precision 步进'
|
|
|
w1, w2 = bili_x, bili_y # w1,w2为自变量和函数值在横纵轴上的放大倍数
|
|
|
# w,h = 750/2,550/2
|
|
|
w, h = x_zhou, y_zhou
|
|
|
xmin, xmax = -math.ceil((loca_y / bili_x)) + 1, math.ceil((canvas_x - loca_y) / bili_x)
|
|
|
# xmax = math.ceil((canvas_x-loca_y) / bili_x)
|
|
|
co2 = []
|
|
|
count = 0
|
|
|
for x in arange(xmin, xmax, draw_precision): # draw_precision----画图精度
|
|
|
y = func(x)
|
|
|
# print(x,y)
|
|
|
# co2.append((x0+w1*x,y0-w2*y))
|
|
|
coord = x0 + w1 * x, y0 - w2 * y, x0 + w1 * x + 1, y0 - w2 * y + 1
|
|
|
|
|
|
# coord = x0+w1*x,y0-w2*y
|
|
|
# coord2 = x0+w1*x+1,y0-w2*y+1
|
|
|
# if abs(x*w1)<w and abs(y*w2)<h and abs(coord[1])<y_zhou:
|
|
|
if abs(coord[1]) < y_zhou: # 超过w,h就截断
|
|
|
# print(coord,type(coord))
|
|
|
co2.append((x0 + w1 * x, y0 - w2 * y))
|
|
|
# co2.append((x0+w1*x+draw_precision,y0-w2*y+draw_precision ))
|
|
|
# print(x,y)
|
|
|
# canvas.create_line(coord,coord2,fill=c,width=2)
|
|
|
|
|
|
for i in range(len(co2)):
|
|
|
if (draw_precision >= 1):
|
|
|
canvas.create_line(co2, fill=c, width=1)
|
|
|
if (i + 1 == len(co2)):
|
|
|
break
|
|
|
if (abs(co2[i][1] - co2[i + 1][1]) > 100):
|
|
|
continue
|
|
|
else:
|
|
|
canvas.create_line(co2[i], co2[i + 1], fill=c, width=1)
|
|
|
print("min,max:", xmin, xmax)
|
|
|
# print(co2,type(co2),len(co2)) #x个数
|
|
|
# canvas.create_line(co2,fill=c,width=1)
|
|
|
# canvas.create_line(co2[:20],fill=c,width=1)
|
|
|
|
|
|
canvas.update()
|
|
|
|
|
|
|
|
|
# y=tan(x)
|
|
|
# y=sin(x)
|
|
|
fx1 = lambda x: sin(x)
|
|
|
print(fx1)
|
|
|
fx2 = lambda x: cos(x)
|
|
|
fx3 = lambda x: tan(x)
|
|
|
fx4 = lambda x: (1 / tan(x)) # cot
|
|
|
fx5 = lambda x: sin(x) + cos(x)
|
|
|
fx6 = lambda x: sin(x) * cos(x)
|
|
|
fx7 = lambda x: sin(x) - cos(x) + tan(x)
|
|
|
fx8 = lambda x: x
|
|
|
fx9 = lambda x: (x ** 2)
|
|
|
|
|
|
width, height = 1200, 800 # 画布与窗口大小相同
|
|
|
x0, y0 = 375, 275 # 四象限原点坐标
|
|
|
# x0,y0 = 20,500 #一象限原点坐标
|
|
|
# xmin,xmax = 10,10 #自变量最大值
|
|
|
x_zhou, y_zhou = 750, 550
|
|
|
|
|
|
# canvas_x ,canvas_y = 800,480 #x,y轴长
|
|
|
canvas_x, canvas_y = x_zhou, y_zhou
|
|
|
origin = (x0, y0) # 原点的x, y像素值
|
|
|
loca_x = origin[1] # 坐标轴 x (在y轴上的)的位置
|
|
|
loca_y = origin[0] # 坐标轴 y (在x轴上的)的位置
|
|
|
bili_x, bili_y = 10, 10 # x20尺度,y40尺度
|
|
|
# draw_precision = 0.01 #画图精度为Δx
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
window = tk.Tk()
|
|
|
canvas = tk.Canvas(window,
|
|
|
bg='#CDCDCD',
|
|
|
height=800,
|
|
|
width=1200)
|
|
|
canvas.pack()
|
|
|
screenwidth = window.winfo_screenwidth() # 居中显示
|
|
|
screenheight = window.winfo_screenheight()
|
|
|
size_geo = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
|
|
|
window.geometry(size_geo)
|
|
|
window.resizable(False, False)
|
|
|
window_open(width, height)
|
|
|
|
|
|
x_show(x_zhou, y_zhou) # GUI界面
|
|
|
|
|
|
window.bind("<Button-1>", leftclick) # 输出鼠标点击坐标
|
|
|
window.mainloop()
|