Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: What is wrong with TPathData.AddArc? Or is it me?


This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 2 - Last Post: Apr 19, 2016 5:16 PM Last Post By: Free Dorfman
Free Dorfman

Posts: 139
Registered: 2/4/12
What is wrong with TPathData.AddArc? Or is it me?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 19, 2016 3:20 PM
Hey all. Another Delphi Mystery!

Delphi Seattle. FMX. Windows 10.

In a nutshell: I am trying (for the first time ever) to use TPathData in a TShape descendant. I was not getting a semicircle where I wanted one. I was getting a HALF circle (with the flat side drawn).

So, some further experimenting and I have created a simple test app that I'm pretty sure demonstrates a bug with TPathData.AddArc.

Or - as is probably the case - I am missing something.

Further notes:
-I have tried changing the order in which these "parts" are drawn.
-I have disabled the code that draws a box around each "part" (procedure FrameIt)
-I have tried using ClosePath at various places (as the code exists here, there is NO call anywhere to ClosePath)

None of the above helped.

Also: I tried SmoothCurveTo, but that was nowhere near a semicircle!

To see this, create a new [Multi-Device Application - Delphi] and simply replace your Unit1 source with the code below, connect TForm1.OnShow, and Run.

NOTE: It looks like the first 4 are correct and the 5th one is missing an edge.
Actually, the 5th one is exactly what I want (albeit flipped) for the 4th one.
It's the 4th one that's problematic.

Any thoughts? Thanks!

unit Unit1;
 
interface
 
uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Objects, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls;
 
type
  TmyShape = class(TShape)
  private
    FPathData: TPathData;
    procedure UpdatePath;
  protected
    procedure Paint; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;
 
 
  TForm1 = class(TForm)
    procedure FormShow(Sender: TObject);
  private
    procedure DoTheShape;
  end;
 
var
  Form1: TForm1;
 
 
 
implementation
 
{$R *.fmx}
 
constructor TmyShape.Create(AOwner: TComponent);
begin
inherited;
FPathData := TPathData.Create;
end;
 
 
destructor TmyShape.Destroy;
begin
FPathData.Free;
inherited;
end;
 
 
procedure TmyShape.UpdatePath;
var
  H, L, R, T, B: single; {height,left,right,top,bottom}
 
  procedure FrameIt;
  const
    delta = 6;
  begin
  FPathData.MoveTo(PointF(L - delta,T - delta));
  FPathData.LineTo(PointF(R + delta,T - delta));
  FPathData.LineTo(PointF(R + delta,B + delta));
  FPathData.LineTo(PointF(L - delta,B + delta));
  FPathData.LineTo(PointF(L - delta,T - delta));
  end;
 
  procedure FirstGo;
  begin
  L := 10;
  R := 30;
  FrameIt;
  end;
 
  procedure NextGo;
  begin
  L := L + 40;
  R := R + 40;
  FrameIt;
  end;
 
begin
FPathData.Clear;
 
H := 20;
T := 10;
B := 30;
 
FirstGo;
//square
FPathData.MoveTo(PointF(L,T));
FPathData.LineTo(PointF(R,T));
FPathData.LineTo(PointF(R,B));
FPathData.LineTo(PointF(L,B));
FPathData.LineTo(PointF(L,T));
 
NextGo;
//triangle
FPathData.MoveTo(PointF(L,T));
FPathData.LineTo(PointF(R,(T + B) / 2));
FPathData.LineTo(PointF(L,B));
FPathData.LineTo(PointF(L,T));
 
NextGo;
//circle
FPathData.MoveTo(PointF(L,T));
FPathData.AddEllipse(RectF(L,T,R,B));
 
NextGo;
//half circle (left-facing)     //THIS ONE IS THE PROBLEM. WHERE IS THE "BASE" COMING FROM??
FPathData.MoveTo(PointF(R,T));
FPathData.AddArc(PointF(R,T + (H / 2)),PointF(H / 2,H / 2),90,180);
 
NextGo;
//half circle (right-facing)
FPathData.MoveTo(PointF(L,T));
FPathData.AddArc(PointF(L,T + (H / 2)),PointF(H / 2,H / 2),-90,180);
end;
 
 
procedure TmyShape.Paint;
begin
UpdatePath;
Canvas.Fill.Assign(Self.Fill);
Canvas.FillPath(FPathData,AbsoluteOpacity);
Canvas.DrawPath(FPathData,AbsoluteOpacity);
end;
 
 
procedure TForm1.DoTheShape;
const
  X =  30;
  Y =  20;
  W = 400;
  H = 100;
var
  S: TmyShape;
begin
S := TmyShape.Create(Self);
S.Parent := Self;
S.SetBounds(X,Y,W,H);
S.Stroke.Thickness := 2;
S.Stroke.Color := TAlphaColorRec.Black;
S.Fill.Color := TAlphaColorRec.Pink;
end;
 
 
procedure TForm1.FormShow(Sender: TObject);
begin
DoTheShape;
end;
 
 
end.
Antonio Estevez

Posts: 665
Registered: 4/12/00
Re: What is wrong with TPathData.AddArc? Or is it me? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 19, 2016 4:05 PM   in response to: Free Dorfman in response to: Free Dorfman
El 20/04/2016 a las 0:24, Free Dorfman escribió:
Hey all. Another Delphi Mystery!

Delphi Seattle. FMX. Windows 10.

In a nutshell: I am trying (for the first time ever) to use TPathData in a TShape descendant. I was not getting a semicircle where I wanted one. I was getting a HALF circle (with the flat side drawn).

NextGo;
//circle
FPathData.MoveTo(PointF(L,T));

This MoveTo is not necessary

FPathData.AddEllipse(RectF(L,T,R,B));

NextGo;
//half circle (left-facing) //THIS ONE IS THE PROBLEM. WHERE IS THE "BASE" COMING FROM??
FPathData.MoveTo(PointF(R,T));
FPathData.AddArc(PointF(R,T + (H / 2)),PointF(H / 2,H / 2),90,180);

I think is a bug, but try using -90,-180

    FPathData.AddArc(PointF(R,T + (H / 2)),PointF(H / 2,H / 2),-90,-180)
Free Dorfman

Posts: 139
Registered: 2/4/12
Re: What is wrong with TPathData.AddArc? Or is it me? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 19, 2016 5:15 PM   in response to: Antonio Estevez in response to: Antonio Estevez
Antonio Estevez wrote:
I think is a bug, but try using -90,-180
    FPathData.AddArc(PointF(R,T + (H / 2)),PointF(H / 2,H / 2),-90,-180)

Wow. Thanks, Antonio. I'm not sure I would have ever thought of that. But it absolutely fixed my problem.

Thanks!
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02