* Add TCubicBezierCurve for Delphi compatibility

This commit is contained in:
Michaël Van Canneyt 2024-07-05 08:59:16 +02:00
parent 6c656a39a4
commit 7f94fb2a65

View File

@ -51,6 +51,20 @@ type
TCubicBezier = array [0..3] of TPointF;
TCubicBezierCurve = record
private
StartPoint: TPointF;
EndPoint: TPointF;
A : Array[1..3] of TPointF;
public
procedure Init(const aA, aB, aC, aD: TPointF);
function CurveLength(aSegments: Integer = 6): Single;
function GetPoint(aIndex, aTotal: Integer): TPointF; overload;
function GetPoint(T: Single): TPointF; overload;
end;
tagVECTOR = record
case Integer of
0: (V: TVectorArray;);
@ -362,6 +376,71 @@ begin
WriteStr(Result,D:7:4);
end;
{ ---------------------------------------------------------------------
TVector
---------------------------------------------------------------------}
procedure TCubicBezierCurve.Init(const aA, aB, aC, aD: TPointF);
begin
StartPoint:=aA;
EndPoint:=aD;
// B(t)=(1-t)^3 * P0 + 3*(1-t)^2 * t * P1 + 3*(1-t)*t^2*P2 + t^3 * P3
// = P0 + 3 (P1-P0)*T + 3 * (P0 -2*P1 + P2) * T^2 + (-P0 + 3*P1 - 3*P2 + P3) * T^3
// = StartPoint + A[1]'*T + A[2]'*T^2 + A[3]*T^3
A[1].X:=(aB.X-aA.X)*3;
A[1].Y:=(aB.Y-aA.Y)*3;
A[2].X:=3*(aA.X - 2 * aB.X + aC.X);
A[2].Y:=3*(aA.Y - 2 * aB.Y + aC.Y);
A[3].X:=-aA.X + aD.X- A[1].X-A[2].X;
A[3].Y:=-aA.Y + aD.Y- A[1].Y-A[2].Y;
end;
function TCubicBezierCurve.GetPoint(aIndex, aTotal: Integer): TPointF;
begin
if aIndex=0 then
Result:=StartPoint
else if aIndex=(aTotal-1) then
Result:=EndPoint
else
Result:=GetPoint(aIndex/(aTotal-1));
end;
function TCubicBezierCurve.GetPoint(T: Single): TPointF;
var
X,Y,T2,T3: Single;
begin
T2:=T*T;
T3:=T*T2;
X:=StartPoint.X+(A[3].X*T3)+(A[2].X*T2)+(A[1].X*T);
Y:=StartPoint.Y+(A[3].Y*T3)+(A[2].Y*T2)+(A[1].Y*T);
Result.X:=X;
Result.Y:=Y;
end;
function TCubicBezierCurve.CurveLength(aSegments: Integer = 6): Single;
var
T, Delta : Single;
I: Integer;
PCurr,PLast: TPointF;
begin
Result:=0;
T:=0;
Delta:=1/aSegments;
PLast:=StartPoint;
for I := 1 to aSegments - 1 do
begin
T:=T+Delta;
PCurr:=GetPoint(T);
Result:=Result+(PCurr-PLast).Length;
PLast:=PCurr;
end;
Result:=Result+(EndPoint-PLast).Length;
end;
{ ---------------------------------------------------------------------
TVector
---------------------------------------------------------------------}