* LCL/Graphics: Fix win32 widgetset Chord method overload with angle arguments to behave like all other widgetsets. Similar to issue #41748. Update related comments in various include files.

This commit is contained in:
wp_xyz 2025-07-11 11:39:10 +02:00
parent a95ed78a60
commit 59dd9c21a0
4 changed files with 54 additions and 23 deletions

View File

@ -72,9 +72,8 @@ function Distance(const Pt, SP, EP : TFloatPoint) : Extended; overload;
function EccentricAngle(const PT : TPoint; const Rect : TRect) : Extended;
procedure EllipseParams2Coords(X, Y, Width, Height: Integer;
Angle1, Angle2: Integer; var SX, SY, EX, EY: Integer);
procedure EllipseParams2Coords(X, Y, Width, Height: Integer; t1, t2: Extended;
var SX, SY, EX, EY: Integer);
function EllipseRadialLength(const Rect : TRect; EccentricAngle : Extended) : Longint;
function EllipsePolygon(const aRect: TRect): TPointArray;
@ -345,37 +344,38 @@ end;
{-------------------------------------------------------------------------------
Method: EllipseParams2Coords
Params: x, y, width, height, angle1, angle2, sx, sy, ex, ey
Params: x, y, width, height, t1, t2, sx, sy, ex, ey
Returns: Nothing
In parametric form, the ellipse equation for every point (x, y) along the
perimeter is
x = a * cos (t), y = b * sin(t)
where a and b are the major and minor half-axes of the ellipse, and t is
an "angle" parameter ranging between 0 and 2*pi.
where a and b are the half-axes of the ellipse, and t is an "angle" parameter
ranging between 0 and 2*pi.
This procedure used by the Windows Arc method calculates the start and end
points, (SX, SY) and (EX, EY), respectively, of an arc beginning at
parameter t = angle1 and ending at parameter t = angle1 + angle2.
But note that angle1 and angle2 are expressed as multiples of 1/16 degree.
Positive values of the angles are in counter-clockwise, negative values in
clockwise direction.
Zero degrees is at 3'o clock position.
parameter t=t1 and ending at parameter t=t2. Note that in the general case
of an eccentric ellipse (no circle) t1 and t2 can not be understood as
polar angles from the ellipse center to the start and end points of the arc.
Nevertheless, positive values of t1 and t2 are in counter-clockwise,
negative values in clockwise direction.
t=0 is at the 3'o clock position. The t parameters are given in radians.
-------------------------------------------------------------------------------}
procedure EllipseParams2Coords(X, Y, Width, Height: Integer;
Angle1, Angle2: Integer; var SX, SY, EX, EY: Integer);
t1, t2: extended; var SX, SY, EX, EY: Integer);
var
sinAngle1, cosAngle1, sinAngle2, cosAngle2: Extended;
sin_t1, cos_t1, sin_t2, cos_t2: Extended;
a, b: Integer;
begin
SinCos(DegToRad(Angle1/16), sinAngle1, cosAngle1);
SinCos(DegToRad((Angle1 + Angle2)/16), sinAngle2, cosAngle2);
SinCos(t1, sin_t1, cos_t1);
SinCos(t2, sin_t2, cos_t2);
a := Width div 2;
b := Height div 2;
SX := X + a + round(cosAngle1 * a);
SY := Y + b - round(sinAngle1 * b);
EX := X + a + round(cosAngle2 * a);
EY := Y + b - round(sinAngle2 * b);
SX := X + a + round(cos_t1 * a);
SY := Y + b - round(sin_t1 * b);
EX := X + a + round(cos_t2 * a);
EY := Y + b - round(sin_t2 * b);
end;
{------------------------------------------------------------------------------

View File

@ -661,6 +661,10 @@ end;
counter-clockwise while negative values mean clockwise direction.
Zero degrees is at the 3'o clock position.
But note that in case of an eccentric ellipse these angles are not the
same as "real" polar angles, but only correspond to the parameter t in the
parametric ellipse equations: x = a * cos(t); y = b * sin(t) where
a and b denote the half axes of the ellipse.
------------------------------------------------------------------------------}
procedure TCanvas.Arc(ALeft, ATop, ARight, ABottom,
Angle16Deg, Angle16DegLength: Integer);
@ -1536,6 +1540,9 @@ end;
Positive values of Angle and AngleLength mean counter-clockwise while negative
values mean clockwise direction. Zero degrees is at the 3'o clock position.
But note that in the case of an eccentric ellipse the angles are not "true"
polar angles, but only the parameter t of the paramatric ellipse equation
(x = a * cos(t), y = b * sin(t), where a and b are the ellipse half axes).
------------------------------------------------------------------------------}
procedure TCanvas.Chord(x1, y1, x2, y2,
Angle16Deg, Angle16DegLength: Integer);
@ -1553,7 +1560,7 @@ end;
Use Chord to draw a filled Chord-shape on the canvas. The values sx,sy,
and ex,ey represent a starting and ending radial-points between which
the Arc is draw.
the Arc is drawn.
------------------------------------------------------------------------------}
procedure TCanvas.Chord(x1, y1, x2, y2, SX, SY, EX, EY: Integer);

View File

@ -45,6 +45,9 @@
Example:
Angle1 = 10*16, Angle2 = 30*16 will draw an arc from 10 to 40 degree.
But note that due to the elliptic eccetricity these angles are not the
same as "real" polar angles, but only correspond to the parameter t in the
parametric ellipse equations: x = a * cos(t); y = b * sin(t)
------------------------------------------------------------------------------}
function TGtk2WidgetSet.Arc(DC: HDC; Left, top, right, bottom, angle1,
angle2: Integer): Boolean;
@ -101,6 +104,9 @@ end;
negative values mean clockwise direction. Zero degrees is at the 3'o clock
position.
But note that in the case of an eccentric ellipse the angles are not "true"
polar angles, but only the parameter t of the paramatric ellipse equation
(x = a * cos(t), y = b * sin(t), where a and b are the ellipse half axes).
------------------------------------------------------------------------------}
function TGtk2WidgetSet.AngleChord(DC: HDC;
x1, y1, x2, y2, angle1, angle2: Integer): Boolean;

View File

@ -49,7 +49,7 @@
But note that due to the elliptic eccetricity these angles are not the
same as "real" polar angles, but only correspond to the parameter t in the
ellipse equations: x = a * cos(t); y = b * sin(t)
parametric ellipse equations: x = a * cos(t); y = b * sin(t)
------------------------------------------------------------------------------}
function TWin32WidgetSet.Arc(DC: HDC; Left, Top, Right, Bottom, Angle16Deg, Angle16DegLength: Integer): Boolean;
var
@ -58,11 +58,17 @@ var
EX: LongInt = 0;
EY: LongInt = 0;
OldArcDirection: Longint;
t1, t2: Extended;
begin
if Angle16DegLength < 0 then OldArcDirection := Windows.SetArcDirection(DC, AD_CLOCKWISE)
else OldArcDirection := Windows.SetArcDirection(DC, AD_COUNTERCLOCKWISE);
EllipseParams2Coords(Left, Top, Right - Left, Bottom - Top, Angle16Deg, Angle16DegLength, SX, SY, EX, EY);
t1 := pi * Angle16Deg / (180*16);
if Angle16DegLength > 360*16 then
t2 := t1 + pi*2.0
else
t2 := pi * (Angle16Deg + Angle16DegLength) / (180*16);
EllipseParams2Coords(Left, Top, Right - Left, Bottom - Top, t1, t2, SX, SY, EX, EY);
Result := Boolean(Windows.Arc(DC, Left, Top, Right, Bottom, SX, SY, EX, EY));
// Revert the arc direction to the previous value
Windows.SetArcDirection(DC, OldArcDirection);
@ -79,13 +85,25 @@ end;
negative values mean clockwise direction. Zero degrees is at the 3'o clock
position.
But note that in the case of an eccentric ellipse the angles are not "true"
polar angles, but only the parameter t of the paramatric ellipse equation
(x = a * cos(t), y = b * sin(t), where a and b are the ellipse half axes).
------------------------------------------------------------------------------}
function TWin32WidgetSet.AngleChord(DC: HDC; x1, y1, x2, y2, angle1,
angle2: Integer): Boolean;
var
SX, SY, EX, EY : Longint;
t1, t2: Extended;
begin
Angles2Coords(x1, y1, x2-x1, y2-y1, Angle1, Angle2, SX{%H-}, SY{%H-}, EX{%H-}, EY{%H-});
t1 := pi * angle1 / (180*16);
if angle2 > 360*16 then
t2 := t1 + pi*2.0
else
t2 := pi * (angle1 + angle2) / (180*16);
if angle2 >= 0 then
EllipseParams2Coords(x1, y1, x2-x1, y2-y1, t1, t2, SX, SY, EX, EY)
else
EllipseParams2Coords(x1, y1, x2-x1, y2-y1, t2, t1, SX, SY, EX, EY);
Result := Boolean(Windows.Chord(DC, x1, y1, x2, y2, SX, SY, EX, EY));
end;