Verständnisfrage zu TEllipseInfoData/TEllipseInfo Class

Rund um die LCL und andere Komponenten
Antworten
Mario Peters
Beiträge: 6
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: 5192
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.

Mario Peters
Beiträge: 6
Registriert: Sa 26. Apr 2025, 22:41

Re: Verständnisfrage zu TEllipseInfoData/TEllipseInfo Class

Beitrag von Mario Peters »

Danke soweit, habe jetzt diesen Code draus gemacht, aber leider wird noch nichts gezeichnet.

Code: Alles auswählen

procedure Draw_Ellipse(aLeft,aTop,aRight,aBottom: Longint);
var
  bounds: windows.TRect;
  canv: TFPPixelCanvas;
  info: TEllipseInfo;
  InfoData: PEllipseInfoData;
  x,y: Longint;
  c: dword;
  r: Longint;
  xtopmin: Longint;
  ytopmin: Longint;
  xtopmax: Longint;
  ytopmax: Longint;
begin
 bounds.Left:=aLeft;
 bounds.Top:=aTop;
 bounds.Right:=aRight;
 bounds.Bottom:=aBottom;
 canv := TFPPixelCanvas.Create;

 info := TEllipseInfo.Create;
 with Canv, info do
   try
     // ElliseInfoRecords erzeugen
     GatherEllipseInfo (bounds);
     // Alle Elemente der InfoList durchlaufen
     x := Round(Info.cx);
     y := Round(Info.cy);
     for r := 0 to x do
     begin
       info.GetInfoForX(x,InfoData);
       with InfoData^ do
       begin
         // Die Pixel des oberen Ellipsenrandes zeichnen
         //info.GetInfoForX(x,InfoData);
         info.GetInfoForX(x,ytopMax,yTopMin,ybotmax,ybotmin);
         for y := ytopmin to ytopmax do
           vipgfx.PutPixelClip (vscreen, x,y, c);    //aus vipgfx Paket von Kirill Kranz
         // Die Pixel des unteren Ellipsenrandes zeichnen
         for y := ybotmin to ybotmax do
           vipgfx.PutPixelClip (vscreen, x,y, c);   //auf vipgfx Paket von Kirill Kranz
           
       end;
     end;
   finally
     info.Free;
   end;
   DrawSolidEllipse(canv,bounds,PaletteFPColor[15]); //aus Ellipses unit von fclimage, zusätzlich um zu sehen ob es mit den Original FPC Units klappt
end;

Leider wird überhaupt nichts gezeichnet. Warum?

Könnte sein dass meine eigene fclimage-Canvas Klasse falsch implementiert ist, da muss ich noch mal nachschauen, aber die vipgfx Routinen sind getestet und funktionieren
ich habe zum Test eigene fclimage Units verwendet, aus fclimage abgeleitet. Will deshalb zum weiteren Test die Originale verwenden. Habe sie in "C:\lazarus\fpc\3.2.2\units\x86_64-win64\fcl-image" auch gefunden und in meinen Projektpfad übernommen. Nun wird aber die Unit fppixlCanv.ppu dennoch nicht gefunden, deren Canvas Klasse ich zum Zeichnen nun verwenden will.

Was kann ich hier machen?

Der Unitpfad ist unter Projekteinstellungen-Pfade unter "Andere Units" eingetragen.

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

Re: Verständnisfrage zu TEllipseInfoData/TEllipseInfo Class

Beitrag von wp_xyz »

Mario Peters hat geschrieben: Di 17. Jun 2025, 18:24 Leider wird überhaupt nichts gezeichnet. Warum?
Dazu kann ich nichts sagen, weil ich diese gfx Bibliothek nicht kenne. Wenn du fcl-image Routinen darin verwenden möchtest, muss es irgendeine Art von Interface zwischen den beiden geben, also wie du ein TFPCustomImage (die Basis-Image-Klasse von fcl-image) in gfx integrieren kannst. Schlimmstenfalls muss du das mit fcl-image erzeugte Bild in einen Stream schreiben und von gfx wieder in die eigenen Klassen einlesen.

In der Lazarus-LCL gibt es die IntfGraphics Routinen, die auf fcl-Image aufbauen und sich ziemlich nahtlos in die LCL-Klassen einfügen. Im Anhang findest du ein Beispiel, wie man das mit fcl-Image in der LCL machen würde. Sinngemäß ähnlich muss es auch mit der gfx-Bibliothek funktionieren.
Mario Peters hat geschrieben: Di 17. Jun 2025, 18:24 In welchem Ordner finde ich denn die fclImage Units? ich habe zum Test eigene verwendet, aus fclimage abgeleitet. Will deshalb zum weiteren Test die Originale verwenden.
Der Quellcode von fcl-image ist im Ordner packages/fcl-image/src des Source-Ordners von FCL (bei einer Standard-Lazarus-Installation ist das (lazarus)/fpc/3.2.2/source).
Dateianhänge
ellipse_forum.zip
(2.76 KiB) 11-mal heruntergeladen

Mario Peters
Beiträge: 6
Registriert: Sa 26. Apr 2025, 22:41

Re: Verständnisfrage zu TEllipseInfoData/TEllipseInfo Class

Beitrag von Mario Peters »

Danke! Da guck ich mir das Ellipse Forum aus der ellipse-forum.zip Datei mal an. Muss doch zu lösen sein, das Problem. Die vipgfx habe ich mir einfach mal aus Interesse runter geladen . Da das nicht funktioniert hat, obwohl von Herrn Kranz als getestet angegeben, Beispiele sind dabei, hat es bei der Ellipse hier nicht funktioniert. Dann halt mit fcl-image oder so wie im Ellipse Forum erklärt. Ich teste weiter und frage hier weider wenn ich irgendwo fest hänge und das Ellipse Forum sollte nicht weiter helfen, Sonst kann ich ja auch dort fragen.

[edit]

Ups, ich sehe gerade dass in der ZIP Datei ja mein Programm ist, nur um die feflenden Teile korrigiert. Guck ich mir jetzt erst mal gründlich an.

Antworten