Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Firemonkey FillEllipse Problem (https://www.delphipraxis.net/179891-firemonkey-fillellipse-problem.html)

CHackbart 9. Apr 2014 10:00

Firemonkey FillEllipse Problem
 
Hi,

hat jemand eventuell eine Idee warum unter Android und iOS eine Ellipse aus so wenigen Polygonen besteht?
Anbei mal ein Beispiel einer Control die lediglich einen Aufnahmeknopf zeichnet. Was unter Windows ausschaut wie es soll, wirkt auf den Mobilgeräten nicht wirklich attraktiv:

Delphi-Quellcode:
unit URecordButton;

interface

uses System.SysUtils, System.Classes, System.Types, System.UITypes,
  FMX.Graphics, FMX.Types, FMX.Controls, FMX.Objects;

type
  TRecordButton = class(TShape)
  protected
    FRecording: Boolean;
    FDiameter: single;

    procedure Paint; override;
    procedure SetDiameter(const Value: single);
  public
    constructor Create(AOwner: TComponent); override;
  published
    property Diameter: single read FDiameter write SetDiameter;
    property Recording: Boolean read FRecording write FRecording;
    property Align;
    property Anchors;
    property ClipChildren default false;
    property ClipParent default false;
    property DesignVisible default True;
    property Enabled default True;
    property Locked default false;
    property Height;
    property HitTest default True;
    property Padding;
    property Opacity;
    property Margins;
    property PopupMenu;
    property position;
    property RotationAngle;
    property RotationCenter;
    property Scale;
    property Visible default True;
    property Width;

    { Mouse events }
    property OnClick;
    property OnDblClick;

    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnMouseWheel;
    property OnMouseEnter;
    property OnMouseLeave;

    property OnPainting;
    property OnPaint;
    property OnResize;
  end;

implementation

constructor TRecordButton.Create(AOwner: TComponent);
begin
  inherited;

  Fill.color := $FFFF0000;
  Stroke.color := $FFFFFFFF;
  Stroke.Kind := TBrushKind.bkSolid;
  Diameter := 32;
end;

procedure TRecordButton.SetDiameter(const Value: single);
begin
  FDiameter := Value;
  Stroke.Thickness := FDiameter / 20;
end;

procedure TRecordButton.Paint;
var
  perc, w: single;
  xp, yp: single;
  color: TAlphaColor;
begin
  if FRecording then
    perc := 0.4
  else
    perc := 0.85;

  w := perc * FDiameter;
  xp := (Width - w) / 2;
  yp := (FDiameter - w) / 2;

  if FRecording then
    canvas.FillRect(RectF(xp, yp, xp + w, yp + w), 0.2 * w, 0.2 * w,
      AllCorners, 1, Fill)
  else
    canvas.FillEllipse(RectF(xp, yp, xp + w, yp + w), 1, Fill);

  xp := (Width - FDiameter) / 2;
  yp := 0;

  canvas.DrawEllipse(RectF(xp, yp, xp + Diameter, yp + Diameter), 1, Stroke);
end;

end.
Christian

Perlsau 9. Apr 2014 11:28

AW: Firemonkey FillEllipse Problem
 
Gleich vorweg: Ich hab nur 2009 und daher keinen blassen Schimmer von Firemonkey. Doch vielleicht hilft dir meine alte Elipsen-Methode weiter:
  • Blatt gibt die Zeichenfläche an,
  • XM und YM den Mittelpunkt,
  • A und B den X- und den Y-Radius,
  • Phi die Drehung um den Mittelpunkt,
  • Pkte die Anzahl der Punkte. 5 Punkte ergibt ein Fünfeck, je mehr Punkte, desto runder wirkt die Elipse.
Delphi-Quellcode:
Procedure Elipse(Blatt: TCanvas; XM,YM,A,B,Phi : REAL; Pkte : BYTE);
Var
  SinPhi, CosPhi,
  SinT,  CosT  : REAL;
  X,Y           : REAL;
  t             : REAL;
  Schritt       : REAL;
  MerkX, MerkY  : REAL;

Begin
  CosPhi := COS(Phi);
  SinPhi := SIN(Phi);
  t     := 0; Schritt := 2 * PI / Pkte;

  SinT := SIN(T); CosT := COS(t);
  MerkX := (A * CosT) * CosPhi + (B * SinT) * SinPhi;
  MerkY := -(A * CosT) * SinPhi + (B * SinT) * CosPhi;

  Repeat
    SinT := SIN(T); CosT := COS(t);
    X := (A * CosT) * CosPhi + (B * SinT) * SinPhi;
    Y := -(A * CosT) * SinPhi + (B * SinT) * CosPhi;

    Blatt.Line(TRUNC(MerkX) + TRUNC(XM), TRUNC(MerkY) + TRUNC(YM),
               TRUNC(X) + TRUNC(XM), TRUNC(Y) + TRUNC(YM));

   MerkX := X; MerkY := Y;
   t := t + Schritt;
 Until t > (2 * PI) + Schritt;
End;

CHackbart 9. Apr 2014 11:59

AW: Firemonkey FillEllipse Problem
 
Danke, das geht auch etwas einfache. Ich denke das Problem liegt in der Umsetzung:
In FMX.Canvas.GPU.helpers:
Delphi-Quellcode:
  SubdivCount := Max(Ceil(2 * Pi * Max(Radius.X, Radius.Y) / MinFlatDistance), 12);
Damit bekommst du einen ziemlich eckigen Kreis, da MinFlatDistance=8 ist.

Union 9. Apr 2014 17:02

AW: Firemonkey FillEllipse Problem
 
Ich hatte das mal gelöst indem ich beim Zeichnen die Scale raufgesetzt habe und danach wieder runterskaliert. Auch die eingebauten TShape unter FMX (TCircle, TEllipse) haben nämlich dieses häßliche Angwohnheit gerne mal wie 8-Ecke auszusehen wenn der Durchmesser sehr klein wird.

Peter666 10. Apr 2014 09:20

AW: Firemonkey FillEllipse Problem
 
Da hätte ich doch eine Frage dazu: Wie optimiert man die Anzeige, so dass nicht bei jeder Änderung eines Textes das komplette Display gerendert wird?

Ich habe in einem Projekt ein 100ms Timer der 4 Labels und eine Listview aktualisiert. Nun habe ich das Gefühl der zeichnet die komplette Anzeige bei jeder Änderung des Labels und des Lisviews komplett neu. Das ganze ist insbesondere bei so hochfrequentem aktualisieren arg langsam. Gibt es so etwas wie führe Änderungen durch und zeichne erst danach regulär die komplette Szene?

Peter

Union 10. Apr 2014 09:39

AW: Firemonkey FillEllipse Problem
 
Vielleicht einen Versuch wert, Canvas.BeginScene und Canvas.EndScene.

Peter666 10. Apr 2014 09:49

AW: Firemonkey FillEllipse Problem
 
Stimmt, das macht am ehesten Sinn. Ich probier es mal aus, wahrscheinlich muss ich dafür etwas mehr als nur 4 Labels auf das Display packen und aktualisieren.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:20 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz