Verständnisfrage zu TEllipseInfoData/TEllipseInfo Class

Rund um die LCL und andere Komponenten
Antworten
Mario Peters
Beiträge: 4
Registriert: Sa 26. Apr 2025, 22:41

Verständnisfrage zu TEllipseInfoData/TEllipseInfo Class

Beitrag von Mario Peters »

Ich studiere gerade den Quelllcode der FCLimage Klassen und bin auf die Unit Ellipses gestoßen und da drin auf die folgenden Definitionen.

Welche Funktion/Bedeutung haben die aufgeführten Datenfelder?

Code: Alles auswählen

PEllipseInfoData = ^TEllipseInfoData;
  TEllipseInfoData = record
    x, ytopmax, ytopmin, ybotmax, ybotmin : integer;
    OnlyTop : boolean;
  end;

  TEllipseInfo = class
  private
    fcx, fcy, frx,fry,
    fa1, fa2, frot : real;
    fx1,fy1, fx2,fy2 : integer;
    InfoList : TList;
    procedure FreeList;
    procedure ClearList;
    function FindXIndex (x:integer) : integer;
    procedure PrepareCalculation (var np:integer; var delta:real);
    function NewInfoRec (anX:integer) : PEllipseInfoData;
    procedure CalculateCircular (const b:TRect; var x,y,rx,ry:real);
  public
    constructor create;
    destructor destroy; override;
    function GetInfoForX (x:integer; var ytopmax,ytopmin,ybotmax,ybotmin:integer):boolean;
    function GetInfoForX (x:integer; var Info:PEllipseInfoData):boolean;
    procedure GatherEllipseInfo (const bounds:TRect);
    procedure GatherArcInfo (const bounds:TRect; alpha1,alpha2:real);
    property cx : real read fcx; // center point
    property cy : real read fcy;
    property rhor : real read frx; // radius
    property rver : real read fry;
    { only usable when created with GatherArcInfo }
    property a1 : real read fa1;    // angle 1 and point on ellipse
    property x1 : integer read fx1;
    property y1 : integer read fy1;
    property a2 : real read fa2;    // angle 2 and point on ellipse
    property x2 : integer read fx2;
    property y2 : integer read fy2;
  end;
  
  Die Prozeduren und Funktonen erlauben keine Viertel oder halben Ellipsen.
  
  Wie könnte ich diese Funktionalität hinzufügen? Unter Anwendung der EllipseInfo Daten.

wp_xyz
Beiträge: 5191
Registriert: Fr 8. Apr 2011, 09:01

Re: Verständnisfrage zu TEllipseInfoData/TEllipseInfo Class

Beitrag von wp_xyz »

Das sind interne Datenstrukturen zum Zeichnen von Ellipsen. Der TEllipseInfoData-Record enthält eine x-Koordinate sowie einen Bereich für die zugehörigen y-Werte des oberen und unteren Ellipsenbogens, an denen Pixel gesetzt werden müssen, um den Rand der Ellipse ohne lücken zu erhalten.

Die Zeiger auf diese Records sind in der InfoList der TEllipseInfo-Klasse gespeichert. Diese Liste selbst ist privat, man kann aber die EllipseInfoData-Werte über die methode GetInfoForX abfragen.

Die EllipseInfoData-records selbst werden in der TEllipseInfo-Methode GatherEllipseInfo erzeugt; dieser wird das die Ellipse umschreibende Rechteck übergeben. CX und CY sind die Koordinaten des Rechteck- und natürlich auch Ellipsen-Mittelpunkts, RHor und RVer sind die horizontalen und vertikalen Radien der Ellipse (die Ellipse ist nicht verdreht, sondern hat Haupt/Nebenachse in x und y Richtung).

Der Umriss einer Ellipse wird dann so gezeichnet:

Code: Alles auswählen

  info := TEllipseInfo.Create;
  with Canv, info do
    try
      // ElliseInfoRecords erzeugen
      GatherEllipseInfo (bounds);
      // Alle Elemente der InfoList durchlaufen
      for r := 0 to InfoList.count-1 do
        with PEllipseInfoData(InfoList[r])^ do
        begin
          // Die Pixel des oberen Ellipsenrandes zeichnen
          for y := ytopmin to ytopmax do
            MyPutPix (Canv, x,y, c);
          // Die Pixel des unteren Ellipsenrandes zeichnen
          for y := ybotmin to ybotmax do
            MyPutPix (Canv, x,y, c);
          end;
    finally
      info.Free;
    end;
GatherEllipseInfo berechnet nur die Daten für ein Viertel der Ellipse und erzeugt die anderen dann durch Spiegelung. Wenn du nur eine viertel oder halbe Ellipse, oder ganz allgemein, einen Bogen brauchst, musst du in GatherEllipseInfo eingreifen und das Zusammenfügen der vier Teile verhindern. ra ist dabei der Winkel mit dem, bei 0 beginnend, die Punkte am Rand der Ellipse durchlaufen werden.

Antworten