Уроки, алгоритмы, программы, примеры

Вход на сайт

Материалы по разделам

Построения
на плоскости (2D)
Графика
в пространстве (3D)
Вычислительная
геометрия
Физическое
моделирование
Фрактальная
графика

Новые комментарии

У Вас число превысит максимальное число int. Можно использовать в Вашем случае uint, но лучше все переписать на double.
Добавление к программе строки glutReshapeFunc(changeSize); приводит к тому, что треугольник перестаёт совсем отрисовываться.
Выдаёт ошибку glut32.dll не найден! При том, что он лежит в System32! Всё решил) Нужно отправить не в System32, а в System.
Спасибо за статью. Я не Ваш студент. Но мне она помогла написать функцию для Канторова множества на Python для черепашки: import turtle def kanter(x, y, d):     if d > 1:         turtle...
Как реализовать в данном примере границы расчёта?

Счетчики и рейтинг

Рейтинг@Mail.ru Яндекс.Метрика
Скриншот к примеру
Среда программирования: 
Brackets build 1.14.2-17770
Статья по теме: 

Программа демонстрирующая интерполяцию сплайнами.
Для задания функции f(x) используется первое поле ввода. Можно использовать все основные математические функции. Поскольку программа написана на Python, для возведения в степень используется два оператора звёздочка **.
Далее необходимо задать значения производной функции на концах отрезка, производная - влияет на кривизну кривой.
В поле [Ax;Bx] задаются интервалы интерполирования.
Можно выбрать положительное число отрезков разбиения функции на равномерной сетке. Если нажать на чекбокс "Случайное разбиение" - сетка будет случайной.

Код программы: 

from tkinter import *
from tkinter import messagebox
from PIL import ImageTk, Image
import numpy as np
import matplotlib.pyplot as plt 
import random
from math import *
 
class Application(Frame):
 
    def __init__(self,master=None):
        super().__init__(master)
        self.grid()
        self.create_widgets()
        self.master.title("Интерполяция сплайном")
        self.master.geometry(f"1100x480+50+50")
        self.master.resizable(False, False)  
 
    def create_widgets(self):
 
        left_frame = Frame(root, width=640, height=480, pady=5).grid(row=0,column=0,sticky="wens")
        right_frame = Frame(root,width=460, height=480, padx=5, pady=5)
        right_frame.grid(row=0,column=1,sticky="wens")
 
#        холст для вывода графика функции и ее апроксимации
        self.canvas = Canvas(left_frame,width=640,height=480)
        self.canvas.grid(row=0, column=0,sticky="wens", pady=5, padx=5)
 
#        ввод функции для интерполяции
        Label(right_frame,text="f(x)=:",font=('Arial',10)).grid(
            row=0, column=0,sticky="w", pady=5, padx=5)
        self.enteredFunction = StringVar()
        Entry(right_frame,textvariable = self.enteredFunction,width=15,font=('Arial',10)).grid(
            row=0,column=1,sticky="w",padx=5,pady=5)
 
#        ввод производной в начальной точке
        Label(right_frame,text="f'(A)=:",font=('Arial',10)).grid(
            row=1, column=0,sticky="w", pady=5, padx=5)
        self.derivativeStart = DoubleVar()
        Entry(right_frame,textvariable = self.derivativeStart,width=15,font=('Arial',10)).grid(
            row=1,column=1,sticky="w",padx=5,pady=5)
 
#        ввод производной в конечной точке
        Label(right_frame,text="f'(B)=:",font=('Arial',10)).grid(
            row=2, column=0,sticky="w", pady=5, padx=5)
        self.derivativeEnd = DoubleVar()
        Entry(right_frame,textvariable = self.derivativeEnd,width=15,font=('Arial',10)).grid(
            row=2,column=1,sticky="w",padx=5,pady=5)
 
#        ввод интервалов интерполирования
        Label(right_frame,text="[Ax;Bx]:",font=('Arial',10)).grid(
            row=3, column=0,sticky="w", pady=5, padx=5)
        self.startPoint = DoubleVar()
        Entry(right_frame,textvariable = self.startPoint,width=15,font=('Arial',10)).grid(
            row=3,column=1,sticky="w",padx=5,pady=5)
        self.endPoint = DoubleVar()
        Entry(right_frame,textvariable = self.endPoint,width=15,font=('Arial',10)).grid(
            row=3,column=2,sticky="w",padx=5,pady=5)
 
#        ввод количества интервалов разбиения
        Label(right_frame,text="Ввести количество интервалов:",font=('Arial',10)).grid(
            row=4, column=0,sticky="w", pady=5, padx=5)
        self.NumberOfIntervals = IntVar()
        Entry(right_frame,textvariable = self.NumberOfIntervals,width=15,font=('Arial',10)).grid(
            row=4,column=1,sticky="w",padx=5,pady=5)
 
#        если  переменная CheckVar = 0 равномерная сетка, случайные абсциссы иначе
        self.CheckVar= IntVar()
        R1 = Checkbutton(right_frame, text = "Случайное разбиение", variable = self.CheckVar, onvalue = 1, offvalue = 0).grid(row=5,column=0,sticky="we",padx=5,pady=5,columnspan=3)
 
#        кнопка для вывода графика
        Button(right_frame,text="Расчитать",font=('Arial',10),command=lambda: self.calc()).grid(
            row=6,column=0,columnspan=3, stick="we",padx=5,pady=5)
 
 
    def calc(self):
#        считываем количество разбиений
        n=self.NumberOfIntervals.get()
        if n == 0: 
            messagebox.showwarning(title="Неверное значение", message="Введите количество интервалов больше 0")
            return
        xi=[]
 
#        равномерная сетка, если не выбранно обратное
        if self.CheckVar.get() == 0: 
            for i in range(0,n+1): 
                xi.append(self.startPoint.get()+i*((self.endPoint.get()-self.startPoint.get())/n))
        else: 
            for i in range(0,n+1): 
                xi.append(random.uniform(self.startPoint.get(),self.endPoint.get()))
#            поскольку точки случайные, для корректного счета сортируем
            xi.sort()
 
#        находим значения y, для введенной функции
        yi=[]
        functionToInterrpolate=eval('lambda x: ' + self.enteredFunction.get())
        for xd in xi: 
            yi.append(functionToInterrpolate(xd))
        h=[]
        hy=[]
 
#        находим дельты между абсциссами и ординатами
        for i in range(1,len(xi)):
            h.append(xi[i]-xi[i-1])
            hy.append(yi[i]-yi[i-1])
 
#        задаем значения производных в концах отрезка интерполирования
        prA=self.derivativeStart.get()
        prB=self.derivativeEnd.get()
 
#        находим коэффициенты для системы линейных уравнений
        N=len(xi)-1
        a=[0]*N
        b=[0]*N
        c=[0]*N
        f=[0]*N
        k1=-0.5
        k2=-0.5
        m1=3*(hy[0]/(h[0]**2)-prA/h[0])
        m2=3*h[len(h)-1]*(prB/h[len(h)-1]-hy[len(hy)-1]/(h[len(h)-1]**2))
        for i in range(1,len(xi)-1):
            a[i]=h[i-1]
            c[i]=-2*(h[i-1]+h[i])
            b[i]=h[i]
            f[i]=-6*(hy[i]/h[i]-hy[i-1]/h[i-1])  
 
#        находим решение трехдиагональной матрицы методом прогонки, вызывая функцию progonka
        res=self.progonka(N,a,b,c,f,k1,k2,m1,m2)
 
#        ищем кубическую функцию для каждого отрезка интерполирования и считаем значения через каждые 0.01
        for i in range(1,len(xi)):
            grX=[]
            grY=[]
            sd=np.arange(xi[i-1],xi[i]+0.01,0.01)
            for st in sd:
                si=1/(6*h[i-1])*(res[i-1]*((xi[i]-st)**3))
                si+=1/6/h[i-1]*(res[i]*((st-xi[i-1])**3))
                si+=(st-xi[i-1])*yi[i]/h[i-1]
                si-=(st-xi[i-1])*h[i-1]*res[i]/6
                si+=(xi[i]-st)*yi[i-1]/h[i-1]
                si-=(xi[i]-st)*h[i-1]*res[i-1]/6
                grY.append(si)
                si=0
#            выводим на график полученные значения функции и точки - между которыми интерполировали
            plt.plot(sd,grY)
            plt.plot(xi[i-1],yi[i-1],'o')
            plt.plot(xi[i],yi[i],'o')
 
#        задаем разбиение отрезка интерполирования с h=0.01 и считаем реальные значения функции
        xfunc=np.arange(self.startPoint.get(),self.endPoint.get()+0.01,0.01)
        yfunc=[]
        for xf in xfunc:
            yfunc.append(functionToInterrpolate(xf))
 
#        выводим реальный график функции
        plt.plot(xfunc,yfunc, color="gray",alpha=0.5,label=self.enteredFunction.get())
        plt.legend()
        plt.savefig("spline.png")
#        вызываем функцию загрузки картинки
        image = self.load_image("spline.png")
#        выводим на холст картинку
        self.set_image(image)
#        очищаем все что было на графике
        plt.clf()
 
#    метод загрузки изображения
    def load_image(self,name):
        img = Image.open(name)
        return ImageTk.PhotoImage(img)
#    метод установки изображения на холст     
    def set_image(self,image):
        self.canvas.delete("all")
        self.canvas.image = image
        self.canvas.create_image(0,0,image= self.canvas.image,anchor='nw')
 
#   метод решающий трехдиагональную матрицу методом прогонки
    def progonka(self,N,a,b,c,f,k1,k2,m1,m2):
        p=[0]*(N+1)
        q=[0]*(N+1)
        s=[0]*(N+1)
        p[1]=k1
        q[1]=m1
        for j in range (1,N): 
            denominator=c[j]-a[j]*p[j]
            p[j+1]=b[j]/denominator
            q[j+1]=(f[j]+a[j]*q[j])/denominator
        s[N]=(k2*q[N]+m2)/(1-k2*p[N])
        for j in range (N-1,-1,-1): 
            s[j]=p[j+1]*s[j+1]+q[j+1]
        return s  
 
root = Tk()
app = Application(master=root)
root.mainloop()

Прикрепленный файлРазмер
tsybrick_example_spline.rar2.67 кб