Python实现三次参数样条曲线、三次Bezier曲线、三次B样条曲线

算法:

Python实现三次参数样条曲线、三次Bezier曲线、三次B样条曲线_第1张图片Python实现三次参数样条曲线、三次Bezier曲线、三次B样条曲线_第2张图片Python实现三次参数样条曲线、三次Bezier曲线、三次B样条曲线_第3张图片Python实现三次参数样条曲线、三次Bezier曲线、三次B样条曲线_第4张图片Python实现三次参数样条曲线、三次Bezier曲线、三次B样条曲线_第5张图片Python实现三次参数样条曲线、三次Bezier曲线、三次B样条曲线_第6张图片Python实现三次参数样条曲线、三次Bezier曲线、三次B样条曲线_第7张图片Python实现三次参数样条曲线、三次Bezier曲线、三次B样条曲线_第8张图片

Python实现三次参数样条曲线、三次Bezier曲线、三次B样条曲线_第9张图片Python实现三次参数样条曲线、三次Bezier曲线、三次B样条曲线_第10张图片Python实现三次参数样条曲线、三次Bezier曲线、三次B样条曲线_第11张图片Python实现三次参数样条曲线、三次Bezier曲线、三次B样条曲线_第12张图片Python实现三次参数样条曲线、三次Bezier曲线、三次B样条曲线_第13张图片Python实现三次参数样条曲线、三次Bezier曲线、三次B样条曲线_第14张图片Python实现三次参数样条曲线、三次Bezier曲线、三次B样条曲线_第15张图片

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()

你可能感兴趣的:(python,开发语言)