Step 3 - Define a Path to Draw the Polygon

From RAD Studio
Jump to: navigation, search

Go Up to Creating a FireMonkey Primitive Control

To paint a polygon, you need to define a path of drawing operation. After you define the path, the Canvas object can fill and draw the given path.

Summary: To create and close a path

  1. Create a TPath object.
  2. MoveTo the starting point (shown as ①).
  3. Go through each Vertex by LineTo ( go through ②, ③, and ④).
  4. Close the path.

Polgyongdrawing.png


You need to define the following additional members (members previously created are not listed here; see previous steps):

type
TRegularPolygon = class(TShape)
private
  FPath: TPathData;
protected
  procedure CreatePath;
public
  destructor Destroy; override;
end;

The intent here is to:

  • Create an instance of TPathData (FPath field) in the constructor
  • Set path information to FPath field at CreatePath
  • Use path information at Paint method as well as PointInObject method (as discussed later)
  • Destroy the instance of FPath field at the destructor.

As in previous steps, CTRL+SHIFT+C creates placeholders for these methods. Implement these methods as follows:

constructor TRegularPolygon.Create(AOwner: TComponent);
begin
  inherited;
  FNumberOfSides := 3;
  FPath := TPathData.Create;
end;

destructor TRegularPolygon.Destroy;
begin
  FreeAndNil(FPath);
  inherited;
end;

procedure TRegularPolygon.CreatePath;
  procedure GoToAVertex(n: Integer; Angle, CircumRadius: Double; 
    IsLineTo: Boolean = True);
  var
    NewLocation: TPointF;
  begin
    NewLocation.X := Width  / 2 + Cos(n * Angle) * CircumRadius;
    NewLocation.Y := Height / 2 - Sin(n * Angle) * CircumRadius;

    if IsLineTo then
      FPath.LineTo(NewLocation)
    else
      FPath.MoveTo(NewLocation);
  end;
var
  i: Integer;
  Angle, CircumRadius: Double;
begin
  Angle        := 2 * PI / FNumberOfSides;
  CircumRadius := Min(ShapeRect.Width / 2, ShapeRect.Height / 2);

  // Create a new Path
  FPath.Clear;

  // MoveTo the first point
  GoToAVertex(0, Angle, CircumRadius, False);

  // LineTo each Vertex
  for i := 1 to FNumberOfSides do
    GoToAVertex(i, Angle, CircumRadius);

  FPath.ClosePath;
end;

Note that you need to add the following uses clause:

uses
System.Math, System.Types;

Previous

Next