首页  编辑  

贝塞尔曲线

Tags: /超级猛料/Picture.图形图像编程/控件和绘图/   Date Created:

在Delph下调用PolyBezier();

procedure TForm1.Button1Click(Sender: TObject);

var point:array[0..6] of Tpoint;

   h:HDC;

begin

h:=getdc(form1.handle);

point[0].x:=25; point[0].y:=25;

point[1].x:=35; point[1].y:=170;

point[2].x:=130;point[2].y:=120;

point[3].x:=150;point[3].y:=150;

point[4].x:=170;point[4].y:=280;

point[5].x:=250;point[5].y:=115;

point[6].x:=250;point[6].y:=225;

polybezier(h,point,7);

end;

PolyBezier 画一系列相连的曲线,每一段包含4个point,第一点是曲线起点,

第二点,第三点指定曲线形状的控制点,第四点是曲线终点。

本例中,1为起点,4为中点,7为终点,2,3,5,6为控制点。

OR 调用canvas.polybezier();

*** Drawing CURVES in Delphi? ***

Solution 1

From: dmitrys@phyast.la.asu.edu (Dmitry Streblechenko)

In article <4uijv6$kf7@newsbf02.news.aol.com,

  gtabsoft2@aol.com (GTABSoft2) wrote:

Does anyone have source code or info on drawing Bezier curves? I must have

it for my component. Please respond to my email address.

I did this some time ago; I was too lazy to learn how to draw Bezier curves using Win API, so I did it using Polyline().

Note I used floating type values for points coordinates, (I used some kind of virtual screen), just change them to integer.

--------------------------------------------------------------------------------

PBezierPoint = ^TBezierPoint;

TBezierPoint = record

 X,Y:double;   //main node

 Xl,Yl:double; //left control point

 Xr,Yr:double; //right control point

end;

//P1 and P2 are two TBezierPoint's, t is between 0 and 1:

//when t=0 X=P1.X, Y=P1.Y; when t=1 X=P2.X, Y=P2.Y;

procedure BezierValue(P1,P2:TBezierPoint; t:double; var X,Y:double);

var t_sq,t_cb,r1,r2,r3,r4:double;

begin

    t_sq := t * t;

    t_cb := t * t_sq;

    r1 := (1 - 3*t + 3*t_sq -   t_cb)*P1.X;

    r2 := (    3*t - 6*t_sq + 3*t_cb)*P1.Xr;

    r3 := (          3*t_sq - 3*t_cb)*P2.Xl;

    r4 := (                     t_cb)*P2.X;

    X  := r1 + r2 + r3 + r4;

    r1 := (1 - 3*t + 3*t_sq -   t_cb)*P1.Y;

    r2 := (    3*t - 6*t_sq + 3*t_cb)*P1.Yr;

    r3 := (          3*t_sq - 3*t_cb)*P2.Yl;

    r4 := (                     t_cb)*P2.Y;

    Y  := r1 + r2 + r3 + r4;

end;

--------------------------------------------------------------------------------

To draw Bezier curve, split interval between P1 and P2 into several intervals based on how coarse you want your Bezier curve look (3 - 4 pixels looks Ok), then in a loop create an array of points using procedure above with t from 0 to 1 and draw that array of points using polyline().

Solution 2

From: saconn@iol.ie (Stephen Connolly)

gtabsoft2@aol.com (GTABSoft2) wrote:

Does anyone have source code or info on drawing Bezier curves? I must have

it for my component. Please respond to my email address.

I'm posting this here - 'cause: 1. I've seen people ask for this before, 2. The reference is so old I just had to. (BTW I have older references than this ;-P)

I'm sure that there is a standard Borland disclaimer to go with this:

--------------------------------------------------------------------------------

(********************************************************************)

(*                         GRAPHIX TOOLBOX 4.0                      *)

(*       Copyright (c) 1985, 87 by  Borland International, Inc.     *)

(********************************************************************)

unit GShell;

interface

{-------------------------------- snip ----------------------------}

procedure Bezier(A : PlotArray; MaxContrPoints : integer;

                var B : PlotArray; MaxIntPoints : integer);

implementation

{-------------------------------- snip ---------------------------}

procedure Bezier{(A : PlotArray; MaxContrPoints : integer;

                var B : PlotArray; MaxIntPoints : integer)};

const

 MaxControlPoints = 25;

type

 CombiArray = array[0..MaxControlPoints] of Float;

var

 N : integer;

 ContrPoint, IntPoint : integer;

 T, SumX, SumY, Prod, DeltaT, Quot : Float;

 Combi : CombiArray;

begin

 MaxContrPoints := MaxContrPoints - 1;

 DeltaT := 1.0 / (MaxIntPoints - 1);

 Combi[0] := 1;

 Combi[MaxContrPoints] := 1;

 for N := 0 to MaxContrPoints - 2 do

   Combi[N + 1] := Combi[N] * (MaxContrPoints - N) / (N + 1);

 for IntPoint := 1 to MaxIntPoints do

 begin

   T := (IntPoint - 1) * DeltaT;

   if T <= 0.5 then

     begin

       Prod := 1.0 - T;

       Quot := Prod;

       for N := 1 to MaxContrPoints - 1 do

         Prod := Prod * Quot;

       Quot := T / Quot;

       SumX := A[MaxContrPoints + 1, 1];

       SumY := A[MaxContrPoints + 1, 2];

       for N := MaxContrPoints downto 1 do

       begin

         SumX := Combi[N - 1] * A[N, 1] + Quot * SumX;

         SumY := Combi[N - 1] * A[N, 2] + Quot * SumY;

       end;

     end

   else

     begin

       Prod := T;

       Quot := Prod;

       for N := 1 to MaxContrPoints - 1 do

         Prod := Prod * Quot;

       Quot := (1 - T) / Quot;

       SumX := A[1, 1];

       SumY := A[1, 2];

       for N := 1 to MaxContrPoints do

       begin

         SumX := Combi[N] * A[N + 1, 1] + Quot * SumX;

         SumY := Combi[N] * A[N + 1, 2] + Quot * SumY;

       end;

     end;

   B[IntPoint, 1] := SumX * Prod;

   B[IntPoint, 2] := SumY * Prod;

 end;

end; { Bezier }

end. { GShell }