Home > front end >  How to Draw a polygon
How to Draw a polygon

Time:07-08

I'm making a program that will draw a Serpenksiy's Triangle on a Decart and Polar coordinate system. I thought that using Polygon() will be perfect for that, but for some reason it does not draw a triangle, it draws a line. I do not understand why, and I can't come up with an answer.

Here is the code:

unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls;
type
  TGraphForm = class(TForm)
    img1: TImage;
    procedure FormActivate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  GraphForm: TGraphForm;

implementation

uses
  Unit1;

{$R *.dfm}

procedure TGraphForm.FormActivate(Sender: TObject);
var
  Ax, Ay, Bx, By, Cx, Cy: integer;
  x0, y0 :integer;
begin
  //взятие параметров  Defining Points of Triangle
  Ax := StrToInt(MainForm.EditAx.Text);
  Ay := StrToInt(MainForm.EditAy.Text);

  Bx := StrToInt(MainForm.EditBx.Text);
  By := StrToInt(MainForm.EditBx.Text);

  Cx := StrToInt(MainForm.EditCx.Text);
  Cy := StrToInt(MainForm.EditCx.Text);

  //0 функции      Center of system (0;0)
  x0 := img1.Width div 2;
  y0 := img1.Height div 2;

  //Оси           Drawing Axis
  with img1.Canvas do
  begin
    MoveTo(x0,0);
    LineTo(x0, ClientHeight);
    MoveTo(0, y0);
    LineTo(ClientWidth, y0);
  end;

  //график

  //главный треугольник
  with img1.Canvas do
  begin
    Polygon ([Point(-Ax x0,-Ay y0), Point(-Bx x0,-By y0), Point(-Cx x0,-Cy y0)]);
  end;
end;

end.

CodePudding user response:

So, with help from Remy Lebeau (the great man) i fixed the problem. Actually, i have no clue how, but now it works. Here is the changed code:

unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, System.Types;
type
  TGraphForm = class(TForm)
    img: TImage;
    procedure FormActivate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  GraphForm: TGraphForm;

implementation
 uses
  Unit1;
{$R *.dfm}

procedure TGraphForm.FormActivate(Sender: TObject);
  var
  // переменные Variables
  Ax, Ay, Bx, By, Cx, Cy: integer;
  x0, y0 :integer;
  scale :integer;
begin
     // координаты вершин  Points of triangle
  Ax := StrToInt(MainForm.EditAx.Text)*-1;
  Ay := StrToInt(MainForm.EditAy.Text)*-1;
  Bx := StrToInt(MainForm.EditBx.Text)*-1;
  By := StrToInt(MainForm.EditBy.Text)*-1;
  Cx := StrToInt(MainForm.EditCx.Text)*-1;
  Cy := StrToInt(MainForm.EditCy.Text)*-1;
   // точка пересечения осей Where is the zero
  x0 := img.Width div 2;
  y0 := img.Height div 2;
  // множитель масштабирования scale multiplier
  scale :=-40;

  with img.Canvas do
    begin
    //рисование осей    drawing Axises
      MoveTo(x0, 0);
      LineTo(x0, img.Height);
      MoveTo(0, y0);
      LineTo(img.Width, y0);
      //Making poligon (triangle)
      Brush.Color := clBlack;
      Polygon( [Point(Ax*scale x0, Ay*-scale y0), Point(Bx*scale x0, By*-scale y0), Point(Cx*scale x0, Cy*-scale y0)] );
    end;
end;
end.

CodePudding user response:

From the comments on the OP's answer, it is clear that the OP doesn't fully understand the concepts involved. To help the OP, I'd like to answer him/her in the comments thread, but due to technical limitations (comment length, formatting, etc.), I am unable to.

Therefore I write this "pseudoanswer" for the benefit of the OP. When the OP has read this answer, I may delete it.


Create a new VCL application. Then add the following OnPaint handler:

procedure TForm1.FormPaint(Sender: TObject);
begin

  // Clear background
  Canvas.Brush.Color := clWhite;
  Canvas.FillRect(ClientRect);

  // Draw a circle
  Canvas.Brush.Color := clNavy;
  var P := ClientRect.CenterPoint;
  Canvas.Ellipse(P.X - 20, P.Y - 20, P.X   20, P.Y   20);

end;

The OnPaint handler is called every time the form needs to redraw itself.

Please note that I first clear the background; otherwise we'll end up with more and more circles as the form is repainted.

Now, we also want to redraw the form every time it is resized. To this end, add a OnResize handler:

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

Screen recording

To further illustrate the principle, let's animate the ball so it bounces in a simulated field of gravity. To this end, add private instance variables to the form:

private
  x,  y,            // position
  vx, vy,           // velocity
  ax, ay: Double;   // acceleration

and in the OnCreate handler, give them initial values:

procedure TForm1.FormCreate(Sender: TObject);
begin
  x := ClientWidth / 2;
  y := ClientHeight / 2;
  vx := 1000;
  vy := 1000;
  ax := 0;
  ay := 6000;
end;

Then add a TTimer to the form, set its Interval to 30 and give it the following OnTimer event handler:

procedure TForm1.Timer1Timer(Sender: TObject);
begin

  const dt = 0.01;

  vx := vx   ax * dt;
  vy := vy   ay * dt;

  x := x   vx * dt;
  y := y   vy * dt;

  if x < 0 then
  begin
    vx := -0.9*vx;
    x := 1;
  end;

  if x > ClientWidth then
  begin
    vx := -0.9*vx;
    x := ClientWidth - 1;
  end;

  if y < 0 then
  begin
    vy := -0.9*vy;
    y := 1;
  end;

  if y > ClientHeight then
  begin
    vy := -0.9*vy;
    y := ClientHeight - 1;
  end;

  Invalidate;

end;

and change the OnPaint handler to

procedure TForm1.FormPaint(Sender: TObject);
begin

  // Clear background
  Canvas.Brush.Color := clWhite;
  Canvas.FillRect(ClientRect);

  // Draw a circle
  Canvas.Brush.Color := clNavy;
  var CentrePoint := Point(Round(x), Round(y));
  const R = 10;
  Canvas.Ellipse(CentrePoint.X - R, CentrePoint.Y - R, CentrePoint.X   R, CentrePoint.Y   R);

end;

You may notice some flickering. To get rid of this, the standard trick is to add a

procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;

message handler to your form class:

procedure TForm1.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
  Message.Result := 1;
end;

For extra fun, add the following OnClick handler:

procedure TForm1.FormClick(Sender: TObject);
begin
  vx := 5000 * (Random   0.5);
  vy := 5000 * (Random   0.5);
end;

Screen recording

  • Related