Автор: dmitrys@phyast.la.asu.edu (Dmitry Streblechenko)
В: У кого-нибудь есть исходный код или какая-либо информация для рисования кривых Безье? Я должен использовать их в своем компоненте. Пожалуйста используйте для ответа мой адрес электронной почты.
О: Я делал это недавно; мне было лениво разбираться с тем, как рисовать кривые Безье с помощью Win API, поэтому я использовал функцию Polyline().
Примечание: для координатных точек я использовал реальные величины типа floating (я применял некоторый тип виртуального экрана), округляя их до целого.
PBezierPoint = ^TBezierPoint;TBezierPoint = recordX,Y:double; //основной узелXl,Yl:double; //левая контрольная точкаXr,Yr:double; //правая контрольная точкаend; //P1 и P2 - две точки TBezierPoint, расположенные между 0 и 1: //когда t=0 X=P1.X, Y=P1.Y; когда 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;begint_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; |
Для рисования кривой Безье разделяем интервал между P1 и P2 на несколько отрезков (их количество влияет на точность воспроизведения кривой, 3 - 4 точки вполне достаточно), затем в цикле создаем массив точек, используем описанную выше процедуру с параметром t от 0 до 1 и рисуем данный массив точек, используя функцию polyline().
Решение 2
В: У кого-нибудь есть исходный код или какая-либо информация для рисования кривых Безье? Я должен использовать их в своем компоненте. Пожалуйста используйте для ответа мой адрес электронной почты.
Я решил ответить на этот крик души - причина?: 1. Не первый раз вижу подобный вопрос, 2. Задача настолько избита, что я без труда нашел ответ в своем архиве. (BTW: У меня есть более старые решения, чем это ;-P)
Тем не менее эта технология жива до сих пор и приносит свои плоды:
(********************************************************************) (* GRAPHIX TOOLBOX 4.0 *) (* Copyright (c) 1985, 87 by Borland International, Inc. *) (********************************************************************) unit GShell; interface {------------------------------ вырезано --------------------------} procedure Bezier(A : PlotArray; MaxContrPoints : integer; var B : PlotArray; MaxIntPoints : integer); implementation {------------------------------ вырезано --------------------------} 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 doCombi[N + 1] := Combi[N] * (MaxContrPoints - N) / (N + 1);for IntPoint := 1 to MaxIntPoints dobeginT := (IntPoint - 1) * DeltaT;if T <= 0.5 thenbeginProd := 1.0 - T;Quot := Prod;for N := 1 to MaxContrPoints - 1 doProd := Prod * Quot;Quot := T / Quot;SumX := A[MaxContrPoints + 1, 1];SumY := A[MaxContrPoints + 1, 2];for N := MaxContrPoints downto 1 dobeginSumX := Combi[N - 1] * A[N, 1] + Quot * SumX;SumY := Combi[N - 1] * A[N, 2] + Quot * SumY;end;endelsebeginProd := T;Quot := Prod;for N := 1 to MaxContrPoints - 1 doProd := Prod * Quot;Quot := (1 - T) / Quot;SumX := A[1, 1];SumY := A[1, 2];for N := 1 to MaxContrPoints dobeginSumX := 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 } |
[000110]