По заданному количеству точек, задаваемых координатами x, y, необходимо построить кривую при помощи метода сглаживания кривой типа β-сплайна.
Создадим форму с двумя полями для ввода и кнопкой. В первое поле вводится количество точек, во второе - координаты точек. Отрицательные значения не поддерживаются. При нажатии на кнопку, поле для рисования заливается цветом clDefault для того, чтобы стереть предыдущие результаты построения(если таковые имеются) и затем строится кривая.
Используемые функции:
getCoords() - отвечает за корректное считывание координат из поля №2
setCoefficients(Index: Integer) - пересчитывает коэффициенты, необходимые для построения β-сплайна
drawSpline() - Строит сплайн, используя коэффициенты, полученные из функции setCoefficients(Index: Integer)
unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls; type { TForm1 } TForm1 = class(TForm) Button1: TButton; Edit1: TEdit; Edit2: TEdit; Label1: TLabel; Label2: TLabel; PaintBox1: TPaintBox; procedure Button1Click(Sender: TObject); procedure getCoords(); procedure setCoefficients(Index: Integer); procedure drawSpline(); private { private declarations } public { public declarations } end; var Form1: TForm1; x : array[1..30] of Double; y : array[1..30] of Double; a3,a2,a1,a0,b0,b1,b2,b3,x1,y1,t : Double; i,j,k,n,len : Integer; s1,s2 : String; implementation {$R *.lfm} { TForm1 } // Считываем координаты procedure TForm1.getCoords(); begin n:= StrToInt(Edit2.Text); s1:=Edit1.Text; i := 1; j:=0; k:=0; len := Length(s1); while j < n do begin Delete(s2,1,n); while (s1[i] <> ' ') and (i < len+1) do begin if s1[i] <> ',' then begin s2:=s2+s1[i]; end; i:=i+1; end; k:=k+1; if (k mod 2)=0 then begin y[j]:=StrToInt(s2); j:=j+1; end else x[j]:=StrToFloat(s2); i:=i+1; end; end; // Считаем коэффициенты для построения сплайна procedure TForm1.setCoefficients(Index: Integer); begin a3:= (-1*x[Index-1]+3*x[Index] - 3*x[Index+1] + x[Index+2])/6; a2 := (x[Index-1] - 2*x[Index] + x[Index+1])/2; a1 := (-1*x[Index-1] + x[Index+1])/2; a0 := (x[Index-1] + 4*x[Index] + x[Index+1])/6; b3 := (-1*y[Index-1]+3*y[Index] - 3*y[Index+1] + y[Index+2])/6; b2 := (y[Index-1] - 2*y[Index] + y[Index+1])/2; b1 := (-1*y[Index-1] + y[Index+1])/2; b0 := (y[Index-1] + 4*y[Index] + y[Index+1])/6; x1:=(((a3*t + a2)*t+a1)*t + a0)*5; y1:=(((b3*t + b2)*t+b1)*t + b0)*5; end; // Отрисовываем сплайн procedure TForm1.drawSpline(); begin with PaintBox1.Canvas do begin while t<1 do begin MoveTo(round(x1), round(y1)); x1:=(((a3*t + a2)*t+a1)*t + a0)*5; y1:=(((b3*t + b2)*t+b1)*t + b0)*5; LineTo(round(x1), round(y1)); t := t + 0.01; end; end; end; procedure TForm1.Button1Click(Sender: TObject); begin with PaintBox1.Canvas do begin Brush.Color:=clDefault; PaintBox1.Canvas.Rectangle(0,0, PaintBox1.Width, PaintBox1.Height); Brush.Color:=clBlack; Form1.getCoords(); for i :=1 to n-3 do//Строим сплайн для 1-4 точек, для 2-5 точек и так далее до n-3..n begin t := 0; Form1.setCoefficients(i); Form1.drawSpline(); end; end; end; end.
Прикрепленный файл | Размер |
---|---|
Исходные коды и исполняемый файл | 884.6 кб |
Комментарии
в коде присутствуют ошибки!
// Считываем координаты
procedure TForm1.getCoords(Sender: TObject);
var j1:longint;
begin
n:= StrToInt(Edit2.Text); //число точек
s1:=Edit1.Text;
s2:='';
i := 1;
j:=1;
k:=0;
len := Length(s1);
while j <= n do
begin
while s1[i] <> ',' do
begin
s2:=s2+s1[i];
i:=i+1;
end;
i:=i+1;
x[j]:=StrToFloat(s2);
s2:='';
while s1[i] <> ' ' do
begin
s2:=s2+s1[i];
i:=i+1;
end;
y[j]:=StrToFloat(s2);
s2:='';
j:=j+1;
end;
end;