Исходник программы - класс, объектами которого являются естественные кубические сплайны по значениям в узлах с равномерным шагом на Си(C++)
Определить класс, объектами которого являются сплайны. Конструктор строит объект как естественный кубический сплайн по значениям в узлах с равномерным шагом.
Код на C++ #include <iostream.h> #include <conio.h> #include <graphics.h> #include <math.h> #include "mouse.h" #include <stdio.h> #define BORD 1 #define NO_BORD 0 #define LEFT 40 #define TOP 40 #define RIGHT 150 #define BOTTOM 150 char gr=0; char *driv="c:\\temp\\bgi"; struct wind//координаты окна {int l,t,dx,dy; }; struct point//структура точки {int x,y; char c;}; struct lin//структура линии {int x1,y1,x2,y2; char c;}; class spline;//сплайн class graphic//класс графического вывода {wind w;//координаты окна char bord;//граница окна friend class spline; public: //конструктор graphic(int k1,int k2,int k3,int k4,char k5=NO_BORD) { if(gr==0) { int dr=VGA,mode=VGAHI; initgraph(&dr,&mode,driv); } w.l=k1; w.t=k2; w.dx=k3; w.dy=k4; bord=k5; gr=1; set();} //диструктор ~graphic(){}; void clear(void) //очистка окна {setviewport(w.l,w.t,w.l+w.dx,w.t+w.dy,1); clearviewport();} void set(void) //подготовка окна {setviewport(w.l,w.t,w.l+w.dx,w.t+w.dy,1); if(bord!=NO_BORD) {setcolor(1); moveto(0,0); lineto(0,w.dy); lineto(w.dx,w.dy); lineto(w.dx,0); lineto(0,0);}} //вывод точки в окно с помощью операции << friend graphic& operator << (graphic &out,point &p) {setviewport(out.w.l,out.w.t,out.w.l+out.w.dx,out.w.t+out.w.dy,1); putpixel(p.x,p.y,p.c); return out; } //вывод линии в окно с помощью операции << friend graphic& operator << (graphic &out,lin &lin) {setviewport(out.w.l,out.w.t,out.w.l+out.w.dx,out.w.t+out.w.dy,1); setcolor(lin.c); line(lin.x1,lin.y1,lin.x2,lin.y2); return out;}}; class spline {float A[4];//коэффициенты кубического сплайна float l,r;//левая и правая граница public: //конструктор spline(float left,float right,float *B) {l=left; r=right; if(l>r)//если левая больше правой { float temp=r; r=l; l=temp;} float X[4][5]; float h,d; int i,j,k; h=(r-l)/3;//шаг //заполняем матрицу X for(i=0;i<4;i++) for(j=0;j<4;j++) {if(j==0)X[i][j]=1; else X[i][j]=pow(l+h*i,j);} for(i=0;i<4;i++) X[i][4]=B[i]; //приводим матрицу к треугольному виду for(i=0;i<3;i++) for(j=i+1;j<4;j++) { d=X[j][i]/X[i][i]; for(k=0;k<5;k++) X[j][k]-=d*X[i][k];} //обратная прогонка A[3]=X[3][4]/X[3][3]; A[2]=(X[2][4]-A[3]*X[2][3])/X[2][2]; A[1]=(X[1][4]-A[3]*X[1][3]-A[2]*X[1][2])/X[1][1]; A[0]=(X[0][4]-A[3]*X[0][3]-A[2]*X[0][2]-A[1]*X[0][1])/X[0][0];} //диструктор ~spline(){delete []A}; //вывод коэффициентов сплайна на экран friend ostream&operator<<(ostream &po,spline &p) {po<<p.A[0]<<"+"<<p.A[1]<<"*x+"<<p.A[2]<<"*x^2+"<<p.A[3]<<"*x^3"; return po;} //кубический сплайн float f(float x) { return A[0]+A[1]*x+A[2]*x*x+A[3]*x*x*x;} //вывод графика в окно с помощью операции << friend graphic& operator <<(graphic &out,spline &s) { float i; float h=(s.r-s.l)/out.w.dx,max=s.f(s.l),min=s.f(s.l),t,c; for(i=s.l;i<s.r;i+=h) { t=s.f(i); if(t>max)max=t; if(t<min)min=t; } c=(min+max)/2;//средняя линия графика lin xy; xy.c=RED; float cy=out.w.dy/(2*(max-c));//корректировка по y xy.x1=0;// первая xy.y1=out.w.dy/2-(s.f(s.l)-c)*cy;// точка float osx=-s.l/h;//оси float osy=out.w.dy/2+c*cy; lin yy={osx,0,osx,out.w.dy,8}; lin xx={0,osy,out.w.dx,osy,8}; out<<xx<<yy; for(xy.x2=0;xy.x2<=out.w.dx;xy.x2++) { xy.y2=out.w.dy/2-(s.f(h*xy.x2+s.l)-c)*cy; out<<xy; xy.x1=xy.x2; xy.y1=xy.y2; } return out;}}; void main (void) {clrscr(); float l,r; float a[4]; cout<<"Введите границы по x\n"<<"Левая:"; cin>>l; cout<<"Правая:"; cin>>r; if(l>r) { float temp=l; l=r; r=temp;} cout<<"Введите точки\n"; for(int i=0;i<4;i++) { cout<<i+1<<":"; cin>>a[i];} //объект - сплайн spline s(l,r,a); //объект - окно graphic window(LEFT,TOP,RIGHT,BOTTOM,BORD); window<<s; gotoxy(1,20); printf("left click for exit"); //с помощью мыши узнаем координаты точки на графике initmouse(); show_cur(1);//показать курсор coor m;//координаты мыши float x,y; float h=(r-l)/RIGHT,max=s.f(l),min=s.f(l),t,c,ii; for(ii=l;ii<r;ii+=h) { t=s.f(ii); if(t>max)max=t; if(t<min)min=t; } c=(min+max)/2; //пока не нажали левую кнопку мыши while(mouse_mode()!=1) { m=get_xy();//получить координаты if(m.x>LEFT&&m.x<RIGHT+LEFT&&m.y>TOP&&m.y<BOTTOM+TOP) { x=(r-l)/RIGHT*(m.x-LEFT)+l; y=min-(m.y-BOTTOM-TOP)*(max-min)/BOTTOM; gotoxy(1,1); printf("%.2f,%.2f ",x,y); }} closegraph(); }
|