Wenn du deine eigene Arc-Routine verwendest, ist das meiste von dem, was ich hier gesagt habe, irrelevant, denn das bezieht sich auf die Probleme mit den LCL-Arc-Routinen in der Graphics-Unit.Mario Peters hat geschrieben: Mi 30. Jul 2025, 12:06 Also wie sähe das aus wenn nicht Canvas.Arc() oder Canvas.Ellipse() verwendet würde, sondern meine eigene aus dem Anfangsbeirag dieses Threads?
Deine eigene Routine aus dem ersten Beitrag verwendet Winkel-Argumente für Bogenanfang und -ende, und diese Winkel werden in die cos- und sin-Funktionen der parametrisierten Ellipsengleichung eingesetzt, d.h. es handelt sich um exzentrische Winkel. Alles prima - egal welches Betriebssystem, immer richtig.
Wenn du zusätzlich auch die Routinen mit den Start-/End-Punkten SX,SY,EX,EY zur Verfügung stellen willst, musst du aus diesen Punkt-Koordinaten die zugehörigen exzentrischen Winkel ermitteln und damit die schon existierende Routine aufrufen. Die Umrechnung macht eigentlich die Prozedur CoordsToAngles in der GraphMath-Unit - nur dass diese fälschlicherweise die Polarwinkel bestimmt. Stattdessen würde ich die richtige Routine neu codieren, ohne GraphMath zu verwenden, evtl nimmst du auch einen anderen Namen:
Code: Alles auswählen
procedure MyCoords2Angles(X, Y, Width, Height : Integer; SX, SY,
EX, EY : Integer; var Angle1, Angle2 : Extended);
var
aRect : TRect;
SP,EP : TPoint;
begin
aRect := Rect(X,Y,X + Width,Y + Height);
SP := Point(SX,SY);
EP := Point(EX,EY);
Angle1 := MyEccentricAngle(SP, aRect);
Angle2 := MyEccentricAngle(EP, aRect);
If Angle2 < Angle1 then
Angle2 := 360*16 - (Angle1 - Angle2)
else
Angle2 := Angle2 - Angle1;
end;
Code: Alles auswählen
function MyEccentricAngle(const PT : TPoint; const Rect : TRect) : Extended;
var
CenterPt : TPoint;
Theta : Extended;
a, b: Extended;
begin
CenterPt := CenterPoint(Rect);
a := Rect.Right - Rect.Left;
b := Rect.Bottom - Rect.Top;
Theta := ArcTan2((CenterPt.Y - PT.Y) * a, (PT.X - CenterPt.X) * b);
Result := RadToDeg(Theta) * 16;
end;
Achtung allerdings: Diese Routinen verwenden die Winkel in den 1/16-Grad-Einheiten. Wenn du, wie in deiner eigenen Routine im ersten Post, lieber direkt Grad verwenden willst, dann musst du den Multiplikator 16 weglassen.
Die nativen gtk2-Zeichenroutinen selbst sind verborgen in Systembibliothken. Das betrifft in diesem Zusammenhang die Arc-Routine mit den Winkel-Argumenten. Die andere Routinen mit den Punkt-Argumenten dagegen kannst du mit dem Debugger durchsuchen. Trick: Füge in deinem Projekt unter "Hinzufügungen und Beeinflussungen" eine neue Option "-gw3" hinzu (ohne ") - damit wird alles mit Dwarf3-Debug-Informationen neu übersetzt, und du kannst mit dem Debugger alle Lazarus-Units erreichen (nicht allerdings die FPC-Routinen der RTL und FCL). Setze einen Breakpoint auf "Canvas.Arc(...)" und, wenn das Programm dort anhält, drücke F7, um in diese Prozedur einzutauchen - wegen des "-gw3" geht das. Unter Linux führt dich das zu TCanvas.Arc (in graphics) mit der Zeile "LCLIntf.RadialArc(...)". Wenn du dort wieder F7 drückt, kommst du zu "Widgetset.RadialArc" und nach nochmaligem F7 auf RadialArc bist du schließlich in lcl/include/intfbaselcl.inc mitMario Peters hat geschrieben: Mi 30. Jul 2025, 12:06 In welcher Unit des Gtk2 finde ich zum Quellcodestudium der GTK Funktionen die genammte Ellipsenfunktion? Die will ich mir der Volständigkeit halber dennnoch ansehen.
Code: Alles auswählen
function TWidgetSet.RadialArc(DC: HDC;
left, top, right, bottom, sx, sy, ex, ey: Integer): Boolean;
var
A1, A2: Extended;
A2i : integer;
begin
Coords2Angles(left, top, right-left, bottom-top, sx, sy, ex, ey, A1, A2);
A2i := RoundToInt(A2);
if A2i = 0 then
A2i := 5760;
Result := Arc(DC, left, top, right, bottom, RoundToInt(A1), A2i);
end;