Построение интерполяционного полинома Лагранжа

lagrange_1.JPG

Построить гладкую кривую, соединяющую упорядоченнное по оси абсцисс множество точек. Использовать для построения интерполяционный полином Лагранжа.

Используйте мышь для расстановки точек на экране по направлению оси абсцисс. Программа проводит гладкую кривую через эти точки и позволяет изменять форму кривой с помощью мыши. Для вычисления промежуточных значений используется интерполяционный полином Лагранжа

где базисные полиномы определяются по формуле:

#include <stdio.h>
#include <conio.h>
#include <graphics.h>
#include <dos.h>
 
#define GD_DIR "C:\\BC31\\BGI"	// Директория egavga.bgi
#define AMOUNT 30		// Максимальное количество узловых точек
 
// Вычисление ординаты точки методом интерполяционного полинома Лагранжа
int CalcLagrange(double x, double *X, double *Y,int pts)	
{
	double y=0, lj;
	for(int j=0;j<pts;j++)
	{
		lj=1;
		for(int i=0;i<pts;i++)
			if(i!=j)
				lj*=(x-X[i])/(X[j]-X[i]);
		y+=Y[j]*lj;
	}
	return y;
}
 
// Процедура рисования кривой
void DrawCurve(double *X, double *Y, int pts)
{
	for(double x=X[0];x<X[pts-1];x+=0.1)
		putpixel(x,CalcLagrange(x,X,Y,pts),LIGHTGREEN);
 
}
 
// Показать/спрятать курсор мыши
void MouseShow(int s, struct REGPACK reg)
{
	if(s==0)
	{
		reg.r_ax=0x02;
		intr(0x33,&reg);
	}
	else
	{
		reg.r_ax=0x01;
		intr(0x33,&reg);
	}
}
 
int main()
{
	struct REGPACK reg;
	int GD,GM;
	int pts=0,	// Количество поставленных точек
	    put=0,	// Ограничитель
	    mp;		// Номер передвигаемой точки
 
 
	double X[AMOUNT],Y[AMOUNT]; // Массивы X и Y координат точек
 
	GD=DETECT;
 
	reg.r_ax=0x00;		
	intr(0x33,&reg);
 
	if(reg.r_ax!=0)
	{
		initgraph(&GD,&GM,GD_DIR);
 
		MouseShow(1,reg);
 
		reg.r_bx=1;	// Необходимо для первого прохода цикла
 
		// Расстановка узловых точек, переход к черчению кривой по нажатию правой кнопки мыши
 
		while(reg.r_bx!=2)
		{
			reg.r_ax=0x03;
			intr(0x33,&reg);
 
			if(reg.r_bx==1)
			{
				if(put==0)	// Следующий блок выполняется один раз за одно нажатие левой кнопки мыши 
				{
					// Поставить узел, записать его координаты
 
					MouseShow(0,reg);
 
					circle(reg.r_cx,reg.r_dx,2);
 
					MouseShow(1,reg);
 
					X[pts]=reg.r_cx;
					Y[pts]=reg.r_dx;
 
					pts++;
					put=1;
				}
			}
			else
				put=0;
		}
 
		DrawCurve(X,Y,pts);
 
		// Изменение кривой путём изменения положения узловых точек		
 
		while(!kbhit())
		{
			reg.r_ax=0x03;
			intr(0x33,&reg);
 
			if(reg.r_bx==1)
			{
 
				if(put==0&&mp==256)	//Нажата левая кнопка, и узловая точка ещё не выбрана
				{
					// Если курсор указывает на узловую точку, то определить её номер 
					put=1;
					for(int l=0;l<pts;l++)
						if((X[l]+9>reg.r_cx)&&(X[l]-9<reg.r_cx)
						 &&(Y[l]+9>reg.r_dx)&&(Y[l]-9<reg.r_dx))
							 mp=l;
				}
				if(mp!=256)	// Перетаскивание выбранной точки
				{
					MouseShow(0,reg);
 
					X[mp]=reg.r_cx;
					Y[mp]=reg.r_dx-4;
 
					cleardevice();
 
					DrawCurve(X,Y,pts);
 
					for(int j=0;j<pts;j++)
						circle(X[j],Y[j],2);
 
					MouseShow(1,reg);
 
					delay(10);
				}
			}
			else
			{
				mp=256;	// Узловая точка не выбрана
				put=0;
			}
		}
 
	}
	else printf("Mouse is not installed.");
	getch();
	return 0;
}

Ключевые слова: 
интерполяция, интерполяционный полином Лагранжа, гладкая кривая, работа с мышью под DOS
ВложениеРазмер
Полином Лагранжа35.49 кб