You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

405 lines
16 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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到1000y为其对应函数值
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轴长yy轴长
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()