damien2008
Осваивающий
- Сообщения
- 178
- Репутация
- 34
всем привет. прошу помощи)
в составлении функции для отрисовки В-сплайна по точкам.; я с трудом разобрался в кривых Безье, перечитал половину Википедии, к сожалению спец. мат. образования нет, читаю 'Роджерс Д. - Алгоритмические основы машинной графики', и 'Математические основы -''- ', не получается пока формулы переводить в код.
необходимо по массиву точек, например
построить В-сплайн. и как быть, если количество точек меняется динамически?
UPD. нашел функцию для делфи 7 для 6 точек, если есть знающие помогите)
в составлении функции для отрисовки В-сплайна по точкам.; я с трудом разобрался в кривых Безье, перечитал половину Википедии, к сожалению спец. мат. образования нет, читаю 'Роджерс Д. - Алгоритмические основы машинной графики', и 'Математические основы -''- ', не получается пока формулы переводить в код.
необходимо по массиву точек, например
Код:
#include <Array.au3>
Local $ArrPoints[7][2]=[[24, 30], _
[55, 17], _
[68, 56], _
[103, 18], _
[155, 59], _
[203, 11], _
[243, 33]]
_ArrayDisplay($ArrPoints)
построить В-сплайн. и как быть, если количество точек меняется динамически?
UPD. нашел функцию для делфи 7 для 6 точек, если есть знающие помогите)
Код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, AppEvnts, ComCtrls;
type
TForm1 = class(TForm)
StatusBar1: TStatusBar;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormCanResize(Sender: TObject; var NewWidth,
NewHeight: Integer; var Resize: Boolean);
private
{ Private declarations }
public
procedure DrawSpline;
end;
const eps =5;
linewidth =3;
var Form1: TForm1;
P : array of TPoint;
m,current,tp : integer;
BMP : TBitmap;
implementation
{$R *.dfm}
procedure TForm1.DrawSpline;
function N0(t:real):real;
begin result:=((1-t)*(1-t)*(1-t))/6; end;
function N1(t:real):real;
begin result:=(3*t*t*t - 6*t*t + 4)/6; end;
function N2(t:real):real;
begin result:=(-3*t*t*t + 3*t*t + 3*t + 1)/6; end;
function N3(t:real):real;
begin result:=(t*t*t)/6; end;
const dt=0.01;
var t : real;
x,y : real;
i : integer;
begin
BMP.Canvas.Pen.Color:=clWhite; BMP.Canvas.Brush.Color:=clWhite;
BMP.Canvas.Rectangle(0,0,bmp.Width,bmp.Height);
i:=0;
while ((m-i)>3) do
begin
BMP.Canvas.Pen.Width:=1;
BMP.Canvas.Pen.Color:=clBlack; BMP.Canvas.Brush.Color:=clBlack;
bmp.Canvas.Ellipse(p[i+0].x-eps,p[i+0].y-eps,p[i+0].x+eps,p[i+0].y+eps);
bmp.Canvas.Ellipse(p[i+1].x-eps,p[i+1].y-eps,p[i+1].x+eps,p[i+1].y+eps);
bmp.Canvas.Ellipse(p[i+2].x-eps,p[i+2].y-eps,p[i+2].x+eps,p[i+2].y+eps);
bmp.Canvas.Ellipse(p[i+3].x-eps,p[i+3].y-eps,p[i+3].x+eps,p[i+3].y+eps);
bmp.Canvas.MoveTo(p[i+0].x,p[i+0].y);
bmp.Canvas.LineTo(p[i+1].x,p[i+1].y);
bmp.Canvas.LineTo(p[i+2].x,p[i+2].y);
bmp.Canvas.LineTo(p[i+3].x,p[i+3].y);
bmp.Canvas.LineTo(p[i+1].x,p[i+1].y);
bmp.Canvas.MoveTo(p[i+0].x,p[i+0].y);
bmp.Canvas.LineTo(p[i+2].x,p[i+2].y);
t:=0;
BMP.Canvas.Pen.Color:=clBlack;
BMP.Canvas.Pen.Width:=linewidth;
while t<1 do
begin
x:=P[i+0].X*N0(t) + P[i+1].X*N1(t) + P[i+2].X*N2(t) + P[i+3].X*N3(t);
y:=P[i+0].Y*N0(t) + P[i+1].Y*N1(t) + P[i+2].Y*N2(t) + P[i+3].Y*N3(t);
if (t=0) then BMP.Canvas.MoveTo(trunc(x),trunc(y)) else
BMP.Canvas.LineTo(trunc(x),trunc(y));
t:=t+dt;
end;
i:=i+1;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
BMP:=TBitmap.Create;
BMP.Width:=Form1.ClientWidth;
BMP.Height:=Form1.ClientHeight;
m:=6; SetLength(P,m);
p[0].X:=10; p[0].Y:=300;
p[1].X:=50; p[1].Y:=30;
p[2].X:=250; p[2].Y:=30;
p[3].X:=300; p[3].Y:=300;
p[4].X:=400; p[4].Y:=300;
p[5].X:=500; p[5].Y:=30;
DrawSpline;
current:=-1;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
BMP.Destroy;
end;
procedure TForm1.FormPaint(Sender: TObject);
begin
BitBlt(Form1.Canvas.Handle,0,0,Form1.ClientWidth, Form1.ClientHeight,BMP.Canvas.Handle,0,0, SRCCOPY);
end;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var i:integer;
begin
for i:=0 to m-1 do
if (abs(P[i].X-X)<eps)and(abs(P[i].Y-Y)<eps) then
begin current:=i; break; end;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if current<0 then exit;
P[current].x:=x; P[current].y:=y;
DrawSpline; FormPaint(nil);
end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
current:=-1;
end;
procedure TForm1.FormCanResize(Sender: TObject; var NewWidth,
NewHeight: Integer; var Resize: Boolean);
begin
BMP.Width:=NewWidth;
BMP.Height:=NewHeight;
DrawSpline;
end;
end.