Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.719 Beiträge
Delphi 12 Athens
|
AW: FMX.Graphics.TCanvas.FillText drehen
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.
|