Search code examples
delphidelphi-7gdi+

Convert TCanvas.Pie coordinates to GDI+ DrawPie


I need to create a procedure e.g:

procedure GdiPie(Canvas: TCanvas; X1: Integer; Y1: Integer; X2: Integer; Y2: Integer; X3: Integer; Y3: Integer; X4: Integer; Y4: Integer);
var gr: TGPGraphics;
begin
  ...
  gr.DrawPie(brush, X1, Y1, X2 - X1, Y2 - Y1, ???) // calculate "startAngle, sweepAngle"
end;

That takes the same parameters as TCanvas.Pie and convert to TGPGraphics.DrawPie which expects parameters: x, y, width, height, startAngle, sweepAngle

X1,Y1,X2,Y3 are easy. But, how can I calculate startAngle, sweepAngle given X3,Y3,X4,Y4?

I have found this link: How to create a pie chart. but still I can't seem to "reverse" it to work.


Solution

  • You can calculate start and end angle using these formulas:

    CX := (X1 + X2) / 2; // center of bounding rectangle
    CY := (Y1 + Y2) / 2;
    aStart := ArcTan2(Y3 - CY, X3 - CX);
    aEnd := ArcTan2(Y4 - CY, X4 - CX);
     SweepAngle := aEnd - AStart
    

    Don't forget about ArcTan range and possible +-2*Pi offset of SweepAngle (calculated as difference)

    One more approach (through dot and cross vector products):

    SweepAngle := ArcTan2((X3 - CX) * (Y4 - CY) - (X4 - CX) * (Y3 - CY),
                          (X3 - CX) * (X4 - CX) + (Y3 - CY) * (Y4 - CY));
    

    It seems you need angles in degrees, so apply RadToDeg function.