0
votes

I am using a PlotGrid component with Firemonkey and I want to be able to draw a parabola in it. Given a very easy program that takes a,b,c as input ( > ax^2 + bx + c = 0) I am going to solve the 2nd degree equation.

As you should know that can be represented with a parabola. I thought that I could use this procedure:

procedure DrawArc(const Center, Radius: TPointF; StartAngle, SweepAngle: Single; const AOpacity: Single); overload;

You can see this picture to better understand the meaning:

enter image description here

I want to be able to draw a parabola in a PlotGrid because the user in this way I can have a "container" for my line. Also, if I resized the component or I am using a mobile device, I won't have to repaint the x/y axis. Is this a good way to go?


I have studied a bit the situation and this is what I have thought:

The focus coords of the parabola should be what in the procedure are called Center. The Radius.X should be the value of one of the solutions of the equations. I The Radius.Y should be the position of the vertex.

I cannot figure how to setup the sweep angle. Is this too complicated? Should I find another better solution to draw the parabola?

1

1 Answers

2
votes

You cannot draw parabola with ellipse arc, it doesn't give needed curve form (only small parabola piece near middle point might be approximated).

If Firemonkey graphics engine supports Bezier curves, you can draw exact parabola with Bezier. To calculate it's coefficients, express X- and Y- parts of parametric cubic curve in power basis

F(x) = -b/2a + (t - 0.5) * needed_parabola_X_range
F(y) = a*F(x)^2 + b * F(x) + c

then transform them into Bernstein polynomial basis (here you need some understanding of Bezier math)

VCL example

var
  a, b, c, w: Double;
  b2a, baw: Double;
  P: array[0..3] of TPoint;
  Cx, Cy: array[0..3] of Double;
begin
  //vertex at (200, 100)
  a := 0.05;
  b := -20;
  c := 2100;
  W := 160; //width, distance between parabola ends
  b2a := - 0.5 * b / a;
  baw := b2a - 0.5 * W;
  Cx[0] := baw;
  Cx[1] := W;
  Cx[2] := 0;
  CX[3] := 0;
  Cy[0] := a * baw * baw + c + b * baw;
  Cy[1] := b * W + 2 * a * W * baW;
  Cy[2] := a * W * W;
  Cy[3] := 0;
  p[0] := Point(Round(Cx[0]), Round(Cy[0]));
  p[1].X := Round(cx[0] + cx[1] / 3);
  p[1].Y := Round(cy[0] + cy[1] / 3);
  p[2].X := Round(cx[0] + (2 * cx[1] + cx[2]) / 3);
  p[2].Y := Round(cy[0] + (2 * cy[1] + cy[2]) / 3);
  p[3].X := Round(cx[0] + cx[1] + cx[2] + cx[3]);
  p[3].Y := Round(cy[0] + cy[1] + cy[2] + cy[3]);
  Canvas.PolyBezier(P);