Patrick Guimaraes
Patrick Guimaraes

Reputation: 27

How can i use TRect in delphi to paint with a angle?

I want to paint something similar to the image? How can I rotate the TRect, to paint with a specific angle?

An image of a rectangle with black border. It is divided into two parts -- a left part and a right part -- by a slanted, not far from vertical, line in the middle, connecting the bottom with the top of the rectangle. The left area is bluish and the right area is white.

Upvotes: 0

Views: 834

Answers (2)

fpiette
fpiette

Reputation: 12322

To rotate your drawing, you can use a Direct2D canvas and set the transformation as a rotation (You can translate, rotate, scale, skew, and combine several of them).

Example:

In your form, add the following:

private
    FD2DCanvas        : TDirect2DCanvas;
    function  CreateD2DCanvas: Boolean;
protected
    procedure CreateWnd; override;

Then implement CreateD2DCanvas() and CreateWnd():

function TForm1.CreateD2DCanvas: Boolean;
begin
    try
       FD2DCanvas.Free;
       FD2DCanvas    := TDirect2DCanvas.Create(Handle);
       Result        := TRUE;
    except
       Result        := FALSE;
    end;
end;
    
procedure TForm1.CreateWnd;
begin
    inherited;
    CreateD2DCanvas;
end;

You must also provide a OnResize event handler like this:

procedure TForm1.FormResize(Sender: TObject);
begin
    // When the windows is resized, we needs to recreate RenderTarget
    CreateD2DCanvas;
    Invalidate;
end;

And finally provide a OnPaint event handler like this:

procedure TForm1.FormPaint(Sender: TObject);
var
    Rect1 : D2D1_RECT_F;
begin
    FD2DCanvas.BeginDraw;
    try
        FD2DCanvas.Brush.Color := clRed;

        FD2DCanvas.RenderTarget.SetTransform(TD2DMatrix3x2F.Identity);
        Rect1 := Rect(50, 70, 80, 100);
        FD2DCanvas.FillRectangle(Rect1);

        FD2DCanvas.RenderTarget.SetTransform(TD2DMatrix3x2F.Rotation(30.0, Rect1.Left, Rect1.Top));

        FD2DCanvas.Brush.Color := clYellow;
        FD2DCanvas.FillRectangle(Rect1);
    finally
        FD2DCanvas.EndDraw;
    end;
end;

Don't forget to add Winapi.D2D1 and Vcl.Direct2D in the uses clause.

The simple example above draw two rectangles (Actually squares), the first not rotated, the second rotated 30 degrees. Of course you can make as many transformations as you like. To combine transformations, you have to multiply them. Warning: this is not commutative: a translation followed by a rotation is not the same as the same rotation followed by the same rotation!

Edit: I wrote a blog post about this topic: https://francois-piette.blogspot.com/2020/08/direct2d-canvas-for-delphi-forms.html

Upvotes: 1

Andreas Rejbrand
Andreas Rejbrand

Reputation: 109128

You need to specify the coordinates of the quadrilateral manually:

procedure TForm1.FormPaint(Sender: TObject);
var
  W10,
  H10,
  Delta: Integer;
begin
  W10 := ClientWidth div 10;
  H10 := ClientHeight div 10;
  Delta := W10;
  Canvas.Brush.Color := clWhite;
  Canvas.FillRect(ClientRect);
  Canvas.Pen.Color := clBlack;
  Canvas.Pen.Width := 8;
  Canvas.Polygon(
    [
      Point(W10, H10),
      Point(W10, ClientHeight - H10),
      Point(ClientWidth - W10, ClientHeight - H10),
      Point(ClientWidth - W10, H10)
    ]
  );
  Canvas.Brush.Color := $E8A200;
  Canvas.Polygon(
    [
      Point(W10, H10),
      Point(W10, ClientHeight - H10),
      Point(ClientWidth div 2 - Delta, ClientHeight - H10),
      Point(ClientWidth div 2 + Delta, H10)
    ]
  );
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  Invalidate;
end;

produces the following output:

Screenshot of the rendered image.

Upvotes: 4

Related Questions