> Нужен исходник по сплайнам , т.е. проведение гладкой кривой > через несколько точек на плоскости ... > Хорошо бы на C++ ... Но разберусь и в инородных > исходниках... > Идею ухватить просто пока не смог ...
program Spline_Draw;
uses crt, graph;
type TPoint = record
X, Y : Real;
end;
const NP = 5;
Res = 50;
var PMas : array [-1..NP+2] of TPoint;
GrDrv, GrMod : Integer;
MaxX, MaxY : Integer;
i, j : Integer;
c : Char;
procedure MakePolinom (C1,C2,C3,C4 : TPoint; T,D : Real; var X,Y : Real);
var T2, T3 : Real;
begin
T2 := Sqr(T);
T3 := T2 * T;
X := ( C1.X*T3 + C2.X*T2 + C3.X*T + C4.X ) / D;
Y := ( C1.Y*T3 + C2.Y*T2 + C3.Y*T + C4.Y ) / D;
end;
procedure CalcBSpline(N : Integer; var C1,C2,C3,C4 : TPoint);
begin
C1.X := -PMas[N-1].X + 3*PMas[N].X -3*PMas[N+1].X + PMas[N+2].X;
C2.X := 3*PMas[N-1].X -6*PMas[N].X + 3*PMas[N+1].X { + 0*PMas[N+2].X};
C3.X := -3*PMas[N-1].X { + 0*PMas[N].X} + 3*PMas[N+1].X { + 0*PMas[N+2].X};
C4.X := PMas[N-1].X + 4*PMas[N].X + PMas[N+1].X { + 0*PMas[N+2].X};
C1.Y := -PMas[N-1].Y + 3*PMas[N].Y -3*PMas[N+1].Y + PMas[N+2].Y;
C2.Y := 3*PMas[N-1].Y -6*PMas[N].Y + 3*PMas[N+1].Y { + 0*PMas[N+2].Y};
C3.Y := -3*PMas[N-1].Y { + 0*PMas[N].Y} + 3*PMas[N+1].Y { + 0*PMas[N+2].Y};
C4.Y := PMas[N-1].Y + 4*PMas[N].Y + PMas[N+1].Y { + 0*PMas[N+2].Y};
end;
procedure CalcCatmullSpline(N : Integer; var C1,C2,C3,C4 : TPoint);
begin
C1.X := -PMas[N-1].X + 3*PMas[N].X - 3*PMas[N+1].X + PMas[N+2].X;
C2.X := 2*PMas[N-1].X - 5*PMas[N].X + 4*PMas[N+1].X - PMas[N+2].X;
C3.X := -PMas[N-1].X { + 0*PMas[N].X } + PMas[N+1].X { + 0*PMas[N+2].X };
C4.X := { 0*PMas[N-1].X } 2*PMas[N].X { + 0*PMas[N+1].X + 0*PMas[N+2].X};
C1.Y := -PMas[N-1].Y + 3*PMas[N].Y - 3*PMas[N+1].Y + PMas[N+2].Y;
C2.Y := 2*PMas[N-1].Y - 5*PMas[N].Y + 4*PMas[N+1].Y - PMas[N+2].Y;
C3.Y := -PMas[N-1].Y { + 0*PMas[N].Y } + PMas[N+1].Y { + 0*PMas[N+2].Y };
C4.Y := { 0*PMas[N-1].Y } 2*PMas[N].Y { + 0*PMas[N+1].Y + 0*PMas[N+2].Y};
end;
procedure DrawBSpline(N, Resolution : Integer);
var i, j : Integer;
X1, Y1, X2, Y2 : Real;
C1, C2, C3, C4 : TPoint;
begin
PMas[-1] := PMas[1];
PMas[0] := PMas[1];
PMas[N+1] := PMas[N];
PMas[N+2] := PMas[N];
for i := 0 to N do
begin
CalcBSpline(i, C1, C2, C3, C4);
MakePolinom(C1, C2, C3, C4, 0, 6, X2, Y2);
for j := 1 to Resolution do
begin
MakePolinom(C1, C2, C3, C4, j/Resolution, 6, X1, Y1);
Line(Round(X2), Round(Y2), Round(X1), Round(Y1));
X2 := X1; Y2 := Y1;
end;
end;
end;
procedure DrawCatmullSpline(N, Resolution : Integer);
var i, j : Integer;
X1, Y1, X2, Y2 : Real;
C1, C2, C3, C4 : TPoint;
begin
PMas[0] := PMas[1];
PMas[N+1] := PMas[N];
for i := 1 to N-1 do
begin
CalcCatmullSpline(i, C1, C2, C3, C4);
MakePolinom(C1, C2, C3, C4, 0, 2, X2, Y2);
for j := 1 to Resolution do
begin
MakePolinom(C1, C2, C3, C4, j/Resolution, 2, X1, Y1);
Line(Round(X1), Round(Y1), Round(X2), Round(Y2));
X2 := X1; Y2 := Y1;
end;
end;
end;
procedure DrawX;
var i : Integer;
begin
for i := 1 to NP do
begin
Line(Round(PMas[i].X-3), Round(PMas[i].Y),
Round(PMas[i].X+3), Round(PMas[i].Y));
Line(Round(PMas[i].X), Round(PMas[i].Y-3),
Round(PMas[i].X), Round(PMas[i].Y+3));
end;
end;
{============================================================================}
begin
Randomize;
GrDrv := Detect;
InitGraph(GrDrv, GrMod, ''); { }
if GraphResult <> GrOk then
begin
Writeln(#10#13, 'Error initializing graphics !');
Writeln('egavga.bgi must be in current dir !', #10#13);
Halt(0);
end;
MaxX := GetMaxX; MaxY := GetMaxY;
repeat
for i := 1 to NP do
begin
PMas[i].X := Random(MaxX);
PMas[i].Y := Random(MaxY);
end;
SetColor(LightRed);
DrawCatmullSpline(NP, Res);
SetColor(LightGreen);
DrawBSpline(NP, Res);
SetColor(Yellow);
DrawX;
c := ReadKey;
ClearDevice;
until c = Chr(27);
CloseGraph; { }
end.
|