Search code examples
delphicanvasdrawing

Delphi. Canvas.Pie 60 Degree Wedge


I have searched all over to find a simple solution. I am new to working with drawing on canvas.

I have had no issues with lines, Circle or rectangle. Pies are boggling me.

What I am trying to do is draw a Wedge with an azimuth of 60 degrees. It needs to start at 300 Degrees and progress to 30 degrees. The wedge needs to be solid green.

The problem I have is I do not quite understand all the parameters.

canvas.pie(x1,y1,x2,y2,x3,y3,x4,y4) -- x1,y1=Top Left -- x2,y2=Width and height, bottom right.

Could someone be a gem and help explain the other 4 parameters or point me to a good description online. Some sample code will also be very handy.

I tried chatGPT to no avail.

I cannot get a result even close


Solution

  • As Philip wrote, X3,Y3 and X4,Y4 are points that intersect the sides of the pie.

    You can use a little trigonometry to calculate the location of these points so they match the angles you want. Here are the steps I followed:

    1. Create a new VCL application
    2. Drop a TPaintBox and TTrackbar on the form
    3. Add System.Math to the form's uses clause
    4. Add the code below to the component events
    5. Run the application and use the trackbar to change the ending angle

    The RADIUS doesn't really matter. I chose 100 arbitrarily. SIN and COS use Radians, but I still think in degrees, so I use DegToRad for the conversion.

    By default, zero degrees points to the right. I subtract 90 from the angle before the conversion so that it points up instead. Adjust to suit your needs.

    You can control the direction that the pie is drawn (clockwise vs counterclockwise) by swapping the values for X3,Y3 and X4,Y4. I think you could also use the SetArcDirection WinAPI call. I haven't messed with that, but it's mentioned in the TCanvas.Arc documentation.

    procedure TForm1.FormCreate(Sender: TObject);
    begin
      TrackBar1.Min := 0;
      TrackBar1.Max := 360;
      TrackBar1.Position := 30;
    end;
    
    procedure TForm1.PaintBox1Paint(Sender: TObject);
    const
      RADIUS = 100;
      DEFAULT_THETA = 60;
    var
      X1, Y1: Integer;
      X2, Y2: Integer;
      X3, Y3: Integer;
      X4, Y4: Integer;
      LStartTheta: Single;
      LEndTheta: Single;
    begin
      X1 := 0;
      Y1 := 0;
      X2 := PaintBox1.Width;
      Y2 := PaintBox1.Height;
    
      LStartTheta := DegToRad(DEFAULT_THETA - 90);
      X3 := Round(RADIUS * Cos(LStartTheta) + PaintBox1.Width / 2);
      Y3 := Round(RADIUS * Sin(LStartTheta) + PaintBox1.Height / 2);
    
      LEndTheta := DegToRad(TrackBar1.Position - 90);
      X4 := Round(RADIUS * Cos(LEndTheta) + PaintBox1.Width / 2);
      Y4 := Round(RADIUS * Sin(LEndTheta) + PaintBox1.Height / 2);
    
      PaintBox1.Canvas.Pen.Color := clWhite;
      PaintBox1.Canvas.Brush.Style := bsSolid;
      PaintBox1.Canvas.Brush.Color := clGreen;
      PaintBox1.Canvas.Pie(X1, Y1, X2, Y2, X3, Y3, X4, Y4);
    end;
    
    procedure TForm1.TrackBar1Change(Sender: TObject);
    begin
      PaintBox1.Invalidate;
    end;
    

    screenshot