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

Вход на сайт

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

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

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

dobryj den, popytalas otkryt prikreplionnyj fail ctoby posmotret kak rabotaet, no mne ego ne pokazyvaet vydajet osibku. Pochemu?
Очень интересно! ии сайт крутой жалко что умирает(
У Вас число превысит максимальное число int. Можно использовать в Вашем случае uint, но лучше все переписать на double.
Добавление к программе строки glutReshapeFunc(changeSize); приводит к тому, что треугольник перестаёт совсем отрисовываться.
Выдаёт ошибку glut32.dll не найден! При том, что он лежит в System32! Всё решил) Нужно отправить не в System32, а в System.

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

Рейтинг@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 кб