LazUtils/GraphMath: Avoid separate calculation of sin() and cos() of the same angle in several functions. Related to issue #39983.

This commit is contained in:
wp_xyz 2022-11-02 23:21:44 +01:00
parent e171cf6f33
commit 969ac2a4bf

View File

@ -353,8 +353,7 @@ procedure Arc2Bezier(X, Y, Width, Height : Longint; Angle1, Angle2,
var var
SinA,CosA : Extended; SinA,CosA : Extended;
begin begin
CosA := cos(Rotation); SinCos(Rotation, SinA, CosA);
SinA := Sin(Rotation);
Result.X := Point.X*CosA + Point.Y*SinA; Result.X := Point.X*CosA + Point.Y*SinA;
Result.Y := Point.X*SinA - Point.Y*CosA; Result.Y := Point.X*SinA - Point.Y*CosA;
end; end;
@ -368,6 +367,7 @@ var
Beta : Extended; Beta : Extended;
P : array[0..3] of TFLoatPoint; P : array[0..3] of TFLoatPoint;
SinA,CosA : Extended; SinA,CosA : Extended;
SinA2o2,CosA2o2: Extended;
A,B : Extended; A,B : Extended;
I : Longint; I : Longint;
PT : TFloatPoint; PT : TFloatPoint;
@ -401,20 +401,19 @@ begin
Angle1 := DegToRad(Angle1/16); Angle1 := DegToRad(Angle1/16);
Angle2 := DegToRad(Angle2/16); Angle2 := DegToRad(Angle2/16);
Rotation := -DegToRad(Rotation/16); Rotation := -DegToRad(Rotation/16);
Beta := (4/3)*(1 - Cos(Angle2/2))/(Sin(Angle2/2)); SinCos(Angle2/2, SinA2o2, CosA2o2);
Beta := (4/3)*(1 - CosA2o2)/SinA2o2;
PT.X := X + Width / 2; PT.X := X + Width / 2;
PT.Y := Y + Height / 2; PT.Y := Y + Height / 2;
CosA := cos(Angle1); SinCos(Angle1, SinA, CosA);
SinA := sin(Angle1);
P[0].X := A *CosA; P[0].X := A *CosA;
P[0].Y := B *SinA; P[0].Y := B *SinA;
P[1].X := P[0].X - Beta * A * SinA; P[1].X := P[0].X - Beta * A * SinA;
P[1].Y := P[0].Y + Beta * B * CosA; P[1].Y := P[0].Y + Beta * B * CosA;
CosA := cos(Angle1 + Angle2); SinCos(Angle1 + Angle2, SinA, CosA);
SinA := sin(Angle1 + Angle2);
P[3].X := A *CosA; P[3].X := A *CosA;
P[3].Y := B *SinA; P[3].Y := B *SinA;
@ -737,13 +736,16 @@ end;
function EllipseRadialLength(const Rect : TRect; EccentricAngle : Extended) : Longint; function EllipseRadialLength(const Rect : TRect; EccentricAngle : Extended) : Longint;
var var
a, b, R : Extended; a, b, R : Extended;
sinAngle, cosAngle: Extended;
begin begin
a := (Rect.Right - Rect.Left) div 2; a := (Rect.Right - Rect.Left) div 2;
b := (Rect.Bottom - Rect.Top) div 2; b := (Rect.Bottom - Rect.Top) div 2;
R := Sqr(a)*Sqr(b); R := Sqr(a)*Sqr(b);
if R <> 0 then if R <> 0 then
R := Sqrt(R / ((Sqr(b)*Sqr(Cos(DegToRad(EccentricAngle/16)))) + begin
(Sqr(a)*Sqr(Sin(DegToRad(EccentricAngle/16)))))); SinCos(DegToRad(EccentricAngle/16), sinAngle, cosAngle);
R := Sqrt(R / (sqr(b*cosAngle) + sqr(a*sinAngle)));
end;
Result := TruncToInt(R); Result := TruncToInt(R);
end; end;
@ -777,8 +779,9 @@ end;
3'o clock position. 3'o clock position.
------------------------------------------------------------------------------} ------------------------------------------------------------------------------}
function LineEndPoint(const StartPoint : TPoint; Angle, Length : Extended) : function LineEndPoint(const StartPoint : TPoint; Angle, Length : Extended) : TPoint;
TPoint; var
sinAngle, cosAngle: Extended;
begin begin
if Angle > 360*16 then if Angle > 360*16 then
Angle := Frac(Angle / 360*16) * 360*16; Angle := Frac(Angle / 360*16) * 360*16;
@ -786,8 +789,9 @@ begin
if Angle < 0 then if Angle < 0 then
Angle := 360*16 - abs(Angle); Angle := 360*16 - abs(Angle);
Result.Y := StartPoint.Y - Round(Length*Sin(DegToRad(Angle/16))); SinCos(DegToRad(Angle/16), sinAngle, cosAngle);
Result.X := StartPoint.X + Round(Length*Cos(DegToRad(Angle/16))); Result.Y := StartPoint.Y - Round(Length*sinAngle);
Result.X := StartPoint.X + Round(Length*cosAngle);
end; end;