Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.722 Beiträge
 
Delphi 12 Athens
 
#3

AW: FMX.Graphics.TCanvas.FillText drehen

  Alt 5. Sep 2025, 01:45
Danke nochmal an Phillip

und der Endkampf mit den Matrizen.


Also die CreateRotation gibt erstmal nur die Richtung vor, von Position 0:0 aus,
dann noch den Nullpunkt der Matrix festlegen
und "von" diesem Nullpunkt aus dann den Text zeichnen.

In diesem Fall die Nullpunkte jeweils in der Mitte (Text mittig im Ziel rotieren)
Delphi-Quellcode:
uses
  System.Math, System.Math.Vectors;

procedure TForm3.FormPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
begin
  var DrawRect := RectF(100, 200, 200, 250);
  var TextRect := RectF(-DrawRect.Width / 2, -DrawRect.Height / 2,
                        +DrawRect.Width / 2, +DrawRect.Height / 2);
  var DMatrix := TMatrix.CreateRotation(DegToRad(Tag));
  DMatrix.m31 := DrawRect.CenterPoint.X;
  DMatrix.m32 := DrawRect.CenterPoint.Y;
  Tag := Tag + 1;

  Canvas.Stroke.Kind := TBrushKind.Solid;
  Canvas.Stroke.Color := TAlphaColors.Red;
  Canvas.Fill.Color := TAlphaColors.Ghostwhite;
  Canvas.FillRect(DrawRect, 1);

  Canvas.SetMatrix(DMatrix);
  Canvas.Fill.Color := TAlphaColors.Black;
  Canvas.FillText(TextRect, 'Rotated FMX Text', False,
    1, [], TTextAlign.Center, TTextAlign.Center);
end;

procedure TForm3.Timer1Timer(Sender: TObject);
begin
  Self.Invalidate;
end;
Da ich aber eh nur 90°-Winkel brauch, kann ich's vereinfachen und an einer Ecke rotieren
(-90° = links-unten, +90° = rechts-oben und 180° = unten-rechts)
Delphi-Quellcode:
uses
  System.Math, System.Math.Vectors;

procedure TForm3.FormPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
begin
  var DrawRect := RectF(100, 200, 200, 250);
  var TextRect := RectF(0, 0, DrawRect.Height, DrawRect.Width)
  var DMatrix := TMatrix.CreateRotation(DegToRad(Tag));
  DMatrix.m31 := DrawRect.Left;
  DMatrix.m32 := DrawRect.Bottom;
  Tag := Tag + 1;

  Canvas.Stroke.Kind := TBrushKind.Solid;
  Canvas.Stroke.Color := TAlphaColors.Red;
  Canvas.Fill.Color := TAlphaColors.Ghostwhite;
  Canvas.FillRect(DrawRect, 1);

  Canvas.SetMatrix(DMatrix);
  Canvas.Fill.Color := TAlphaColors.Black;
  Canvas.FillText(TextRect, 'Rotated FMX Text', False,
    1, [], TTextAlign.Leading, TTextAlign.Leading);
end;

procedure TForm3.Timer1Timer(Sender: TObject);
begin
  Self.Invalidate;
end;
Und da ich hier ja eh nur mit 90°-Winkeln arbeite, lassen viele Berechnungen (Sinus und Cosinus) durch Konstanten ersetzen.
Delphi-Quellcode:
uses
  System.Math, System.Math.Vectors;

type
  TMatrixHelper = record helper {(TMatrixConstants)} for TMatrix
    const Identity: TMatrix = (m11: +1; m12: 0; m13: 0; m21: 0; m22: +1; m23: 0; m31: 0; m32: 0; m33: 1);
    const Degree180: TMatrix = (m11: -1; m12: 0; m13: 0; m21: 0; m22: -1; m23: 0; m31: 0; m32: 0; m33: 1);
    const Degree90: TMatrix = (m11: 0; m12: +1; m13: 0; m21: -1; m22: 0; m23: 0; m31: 0; m32: 0; m33: 1);
    const Degree270: TMatrix = (m11: 0; m12: -1; m13: 0; m21: +1; m22: 0; m23: 0; m31: 0; m32: 0; m33: 1);
    constructor Create(m11, m12, m13, m21, m22, m23, m31, m32, m33: Single); overload; // 3D-Matrix
    constructor Create(m11, m12, m21, m22, m31, m32: Single); overload; // 2D-Matrix
    constructor Create90 (m31, m32: Single);
    constructor Create180(m31, m32: Single);
    constructor Create270(m31, m32: Single);
  end;

procedure TForm3.FormPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
begin
  // unten-links / hochzu von rechts
  var DrawRect := RectF(100, 100, 120, 200);
  var TextRect := RectF(0, 0, DrawRect.Height, DrawRect.Width);
  var DMatrix := TMatrix.CreateRotation(DegToRad(-90));
  DMatrix.m31 := DrawRect.Left;
  DMatrix.m32 := DrawRect.Bottom;
  // besser als Konstante, da die Berechnung nicht genau 0 ergibt (-4.37113882867379e-08)
  //DMatrix := TMatrix.Create(0, -1, +1, 0, DrawRect.Left, DrawRect.Bottom);

  Canvas.Stroke.Kind := TBrushKind.Solid;
  Canvas.Stroke.Color := TAlphaColors.Red;
  Canvas.Fill.Color := TAlphaColors.Ghostwhite;
  Canvas.FillRect(DrawRect, 1);

  Canvas.SetMatrix(DMatrix);
  Canvas.Fill.Color := TAlphaColors.Black;
  Canvas.FillText(TextRect, ' Rotated FMX Text', False, 1, [], TTextAlign.Leading, TTextAlign.Center);
  Canvas.SetMatrix(TMatrix.Identity);

  // oben-rechts / runterzu von links
  DrawRect := RectF(200, 100, 220, 200);
  TextRect := RectF(0, 0, DrawRect.Height, DrawRect.Width); // ergibt natürlich das Gleiche, wie oben
  DMatrix := TMatrix.CreateRotation(DegToRad(+90));
  DMatrix.m31 := DrawRect.Right;
  DMatrix.m32 := DrawRect.Top;
  // besser als Konstante, da die Berechnung nicht genau 0 ergibt (-4.37113882867379e-08)
  //DMatrix := TMatrix.Create(0, +1, -1, 0, DrawRect.Right, DrawRect.Top);

  Canvas.Stroke.Kind := TBrushKind.Solid;
  Canvas.Stroke.Color := TAlphaColors.Red;
  Canvas.Fill.Color := TAlphaColors.Ghostwhite;
  Canvas.FillRect(DrawRect, 1);

  Canvas.SetMatrix(DMatrix);
  Canvas.Fill.Color := TAlphaColors.Black;
  Canvas.FillText(TextRect, ' Rotated FMX Text', False, 1, [], TTextAlign.Leading, TTextAlign.Center);
  Canvas.SetMatrix(TMatrix.Identity);

  // rechts-unten / kopfüber
  DrawRect := RectF(300, 100, 400, 120);
  TextRect := RectF(0, 0, DrawRect.Width, DrawRect.Height);
  DMatrix := TMatrix.CreateRotation(DegToRad(180));
  DMatrix.m31 := DrawRect.Right;
  DMatrix.m32 := DrawRect.Bottom;
  // besser als Konstante, da die Berechnung nicht genau 0 ergibt (-4.37113882867379e-08)
  //DMatrix := TMatrix.Create(-1, 0, 0, +1, DrawRect.Right, DrawRect.Bottom);

  Canvas.Stroke.Kind := TBrushKind.Solid;
  Canvas.Stroke.Color := TAlphaColors.Red;
  Canvas.Fill.Color := TAlphaColors.Ghostwhite;
  Canvas.FillRect(DrawRect, 1);

  Canvas.SetMatrix(DMatrix);
  Canvas.Fill.Color := TAlphaColors.Black;
  Canvas.FillText(TextRect, ' Rotated FMX Text', False, 1, [], TTextAlign.Leading, TTextAlign.Center);
  Canvas.SetMatrix(TMatrix.Identity);
end;

procedure TForm3.Timer1Timer(Sender: TObject);
begin
  Self.Invalidate;
end;
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat