用DELPHI实现Bezier曲线[转]

来源:互联网 发布:网络舆论和网络舆情 编辑:程序博客网 时间:2024/05/21 09:00
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, AppEvnts, ExtCtrls;

type
TPoint2=packed record//二维顶点数据结构
x:single;
y:single;
end;

TBezierRecord=packed Record//Bezier曲线数据结构
p1:TPoint2;//曲线的开始点
p2:TPoint2;//曲线的控制点
p3:TPoint2;//曲线的控制点
p4:TPoint2;//曲线的结束点
end;

TForm1 = class(TForm)
ApplicationEvents1: TApplicationEvents;
procedure ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
Point:TBezierRecord;
public
{ Public declarations }
procedure DrawBezier(const BezierRecord:TBezierRecord);
function Qt(const t:single;const BezierRecord:TBezierRecord):TPoint2; //t的范围在0-1之间,根据输入求出曲线上点的位置
end;

function Point2(const x:single;const y:single):TPoint2;
function P2AddP2(const P1:TPoint2;const P2:Tpoint2):TPoint2;//两点相加
function singleMultyP2(const t:single;const P:TPoint2):TPoint2;//两点相乘

var
Form1: TForm1;

implementation

{$R *.dfm}
var
step:integer=0;//控制绘制速度的
Xstep:single=0.0; //控制曲线的X轴变化

function singleMultyP2(const t:single;const P:TPoint2):TPoint2;
begin
result.x:=t*p.x;
result.y:=t*p.y;
end;

function P2AddP2(const P1:TPoint2;const P2:Tpoint2):TPoint2;
begin
result.x:=p1.x+p2.x;
result.y:=p1.y+p2.y;
end;

function Point2(const x:single;const y:single):TPoint2;
begin
result.x:=x;
result.y:=y;
end;

procedure TForm1.ApplicationEvents1Idle(Sender: TObject;
var Done: Boolean);
begin
inc(step);
if step>100 then
step:=0;
if (step mod 2)=0 then
begin
DrawBezier(Point);
end;
end;

procedure TForm1.DrawBezier(const BezierRecord:TBezierRecord);
var
t:single;
p:TPoint2;
begin
t:=0;
XStep:=0;
while t<=1 do
begin
t:=(Xstep/(BezierRecord.p4.x-BezierRecord.p1.x));
p:=Qt(t,BezierRecord);
self.Canvas.Pixels[trunc(p.x),trunc(p.y)]:=clred; //绘制
Xstep:=Xstep+0.5;//00.5为步幅
end;
end;

function TForm1.Qt(const t:single;const BezierRecord:TBezierRecord):TPoint2;
var
r0,r1,r2,r3:TPoint2;
begin
r0:=singleMultyP2((1-t)*(1-t)*(1-t),BezierRecord.p1);
r1:=singleMultyP2(3*t*(1-t)*(1-t),BezierRecord.p2);
r2:=singleMultyP2(3*t*t*(1-t),BezierRecord.p3);
r3:=singleMultyP2(t*t*t,BezierRecord.p4);

result:=P2AddP2(P2AddP2(r0,r1),P2AddP2(r2,r3));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Point.p1:=Point2(100,100);
Point.p4:=Point2(500,100);
Point.p2:=Point2(100,0);
Point.p3:=Point2(500,200);
end;

end. 
原创粉丝点击