算法:
import matplotlib.pyplot as plt
import numpy as np
import tkinter as tk
from tkinter import *
import tkinter.messagebox
import tkinter.simpledialog
import tkinter.colorchooser
class Draw:
def __init__(self):
window = Tk()
window.title("曲线")
frame = Frame(window)
frame.pack()
window.geometry("400x300+500+300")
button = Button(frame, text="三次参数样条曲线", command=self.KickHermite)
button.grid(row=1, column=0)
button = Button(frame, text="三次Bezier曲线", command=self.KickBezier)
button.grid(row=1, column=1)
button = Button(frame, text="三次B样条曲线", command=self.KickByangt)
button.grid(row=1, column=2)
Label(frame, text="").grid(row=2, column=1)
Label(frame, text="请输入第一个点的横坐标:").grid(row=3, column=0)
Label(frame, text="请输入第一个点的纵坐标:").grid(row=4, column=0)
Label(frame, text="请输入第二个点的横坐标:").grid(row=5, column=0)
Label(frame, text="请输入第二个点的纵坐标:").grid(row=6, column=0)
Label(frame, text="请输入第三个点的横坐标:").grid(row=7, column=0)
Label(frame, text="请输入第三个点的纵坐标:").grid(row=8, column=0)
Label(frame, text="请输入第四个点的横坐标:").grid(row=9, column=0)
Label(frame, text="请输入第四个点的纵坐标:").grid(row=10, column=0)
self.entry_x1 = Entry(frame,width=5,justify=tk.LEFT)
self.entry_y1 = Entry(frame,width=5,justify=tk.LEFT)
self.entry_x2 = Entry(frame,width=5,justify=tk.LEFT)
self.entry_y2 = Entry(frame,width=5,justify=tk.LEFT)
self.entry_x3 = Entry(frame,width=5,justify=tk.LEFT)
self.entry_y3 = Entry(frame,width=5,justify=tk.LEFT)
self.entry_x4 = Entry(frame,width=5,justify=tk.LEFT)
self.entry_y4 = Entry(frame,width=5,justify=tk.LEFT)
self.entry_x1.grid(row=3, column=1)
self.entry_y1.grid(row=4, column=1)
self.entry_x2.grid(row=5, column=1)
self.entry_y2.grid(row=6, column=1)
self.entry_x3.grid(row=7, column=1)
self.entry_y3.grid(row=8, column=1)
self.entry_x4.grid(row=9, column=1)
self.entry_y4.grid(row=10, column=1)
self.num=100#曲线所取的点的个数,越大越平滑
#Hermite(100)
window.mainloop()
def KickHermite(self):
self.Hermite()
def KickBezier(self):
self.Bezier()
def KickByangt(self):
self.Byangt()
def Hermite(self):
t=0
H0 = np.zeros(self.num+1)
H1 = np.zeros(self.num+1)
H2 = np.zeros(self.num+1)
H3 = np.zeros(self.num+1)
for i in range(0,self.num+1):
H0[i]=2*t**3-3*t**2+1
H1[i]=-2*t**3+3*t**2
H2[i]=t**3-2*t**2+t
H3[i]=t**3-t**2
t=t+(1/self.num)
x=np.zeros(self.num+1)
y=np.zeros(self.num+1)
#p=[(2,3),(8,3.5),(1,1),(1,-1)]
try:
x1=int(self.entry_x1.get())
x2=int(self.entry_x2.get())
x3=int(self.entry_x3.get())
x4= int(self.entry_x4.get())
y1= int(self.entry_y1.get())
y2= int(self.entry_y2.get())
y3= int(self.entry_y3.get())
y4 =int(self.entry_y4.get())
except ValueError:
tkinter.messagebox.showerror("错误","请输入有效数字")
p=[(x1,y1),(x2,y2),(x3,y3),(x4,y4)]
for i in range(0,self.num+1):
x[i]=H0[i]*p[0][0]+H1[i]*p[1][0]+H2[i]*p[2][0]+H3[i]*p[3][0]
y[i]=H0[i]*p[0][1]+H1[i]*p[1][1]+H2[i]*p[2][1]+H3[i]*p[3][1]
self.DrawHermite(x,y,p)
def Bezier(self):
#p=[(2,4),(4,7),(8,7),(10,2)]
try:
x1=int(self.entry_x1.get())
x2=int(self.entry_x2.get())
x3=int(self.entry_x3.get())
x4= int(self.entry_x4.get())
y1= int(self.entry_y1.get())
y2= int(self.entry_y2.get())
y3= int(self.entry_y3.get())
y4 =int(self.entry_y4.get())
except ValueError:
tkinter.messagebox.showerror("错误","请输入有效数字")
p=[(x1,y1),(x2,y2),(x3,y3),(x4,y4)]
A0=p[0][0]
B0=p[0][1]
A1=-3*p[0][0]+3*p[1][0]
B1=-3*p[0][1]+3*p[1][1]
A2=3*p[0][0]-6*p[1][0]+3*p[2][0]
B2=3*p[0][1]-6*p[1][1]+3*p[2][1]
A3=-p[0][0]+3*p[1][0]-3*p[2][0]+p[3][0]
B3=-p[0][1]+3*p[1][1]-3*p[2][1]+p[3][1]
x=np.zeros(100)
y=np.zeros(100)
t=0
for i in range(0,self.num):
x[i]=A0+A1*t+A2*t**2+A3*t**3
y[i]=B0+B1*t+B2*t**2+B3*t**3
t=t+(1/self.num)
self.DrawBezier(x,y,p)
def Byangt(self):
#p = [(2, 4), (4, 7), (8, 7), (10, 2)]
try:
x1=int(self.entry_x1.get())
x2=int(self.entry_x2.get())
x3=int(self.entry_x3.get())
x4= int(self.entry_x4.get())
y1= int(self.entry_y1.get())
y2= int(self.entry_y2.get())
y3= int(self.entry_y3.get())
y4 =int(self.entry_y4.get())
except ValueError:
tkinter.messagebox.showerror("错误","请输入有效数字")
p=[(x1,y1),(x2,y2),(x3,y3),(x4,y4)]
A0 =(p[0][0]+4*p[1][0]+p[2][0])/6
B0 =(p[0][1]+4*p[1][1]+p[2][1])/6
A1 =-(p[0][0]-p[2][0])/2
B1 =-(p[0][1]-p[2][1])/2
A2 =(p[0][0]-2*p[1][0]+p[2][0])/2
B2 =(p[0][1]-2*p[1][1]+p[2][1])/2
A3 =-(p[0][0]-3*p[1][0]+3*p[2][0]-p[3][0])/6
B3 =-(p[0][1]-3*p[1][1]+3*p[2][1]-p[3][1])/6
x = np.zeros(100)
y = np.zeros(100)
t = 0
for i in range(0, self.num):
x[i] = A0 + A1 * t + A2 * t ** 2 + A3 * t ** 3
y[i] = B0 + B1 * t + B2 * t ** 2 + B3 * t ** 3
t = t + (1 / self.num)
self.DrawByangt(x, y, p)
def DrawHermite(self,x,y,p):
plt.figure()
plt.title('三次参数样条曲线')
plt.plot(x,y)
plt.rcParams['font.sans-serif'] = ['Kaitt', 'SimHei']# 汉字字体,优先使用楷体,找不到则使用黑体
plt.rcParams['axes.unicode_minus'] = False# 正常显示负号
x1=p[0][0]
y1=p[0][1]
x2=p[1][0]
y2=p[1][1]
xpoint=(x1,x2)
ypoint=(y1,y2)
plt.scatter(xpoint,ypoint,s=40,c='r')
plt.show()
def DrawBezier(self,x, y, p):
plt.figure()
plt.title('三次Beizer曲线')
plt.plot(x, y)
plt.rcParams['font.sans-serif'] = ['Kaitt', 'SimHei'] # 汉字字体,优先使用楷体,找不到则使用黑体
plt.rcParams['axes.unicode_minus'] = False # 正常显示负号
x1 = p[0][0]
y1 = p[0][1]
x2 = p[1][0]
y2 = p[1][1]
x3 = p[2][0]
y3 = p[2][1]
x4 = p[3][0]
y4 = p[3][1]
xpoint = (x1, x2,x3,x4)
ypoint = (y1, y2,y3,y4)
plt.scatter(xpoint, ypoint, s=40, c='r')
plt.plot(xpoint, ypoint,)
plt.show()
def DrawByangt(self,x, y, p):
plt.figure()
plt.title('三次B样条曲线')
plt.plot(x, y)
plt.rcParams['font.sans-serif'] = ['Kaitt', 'SimHei'] # 汉字字体,优先使用楷体,找不到则使用黑体
plt.rcParams['axes.unicode_minus'] = False # 正常显示负号
x1 = p[0][0]
y1 = p[0][1]
x2 = p[1][0]
y2 = p[1][1]
x3 = p[2][0]
y3 = p[2][1]
x4 = p[3][0]
y4 = p[3][1]
xpoint = (x1, x2, x3, x4)
ypoint = (y1, y2, y3, y4)
plt.scatter(xpoint, ypoint, s=40, c='r')
plt.plot(xpoint, ypoint )
plt.show()
Draw()