Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to calculate the vertex of a parabola given three points

I have three X/Y points that form a parabola. I simply need to calculate what the vertex of the parabola is that goes through these three points. Preferably a quick way as I have to do a LOT of these calculations!

The "Ask A Scientist" website provides this answer:

The general form of a parabola is given by the equation: A * x^2 + B * x + C = y where A, B, and C are arbitrary Real constants. You have three pairs of points that are (x,y) ordered pairs. Substitute the x and y values of each point into the equation for a parabola. You will get three LINEAR equations in three unknowns, the three constants. You can then easily solve this system of three equations for the values of A, B, and C, and you'll have the equation of the parabola that intersects your 3 points. The vertex is where the first derivative is 0, a little algebra gives: ( -B/2A , C - B^2/4A ) for the vertex.

It would be nice to see actual code that does this calculation in C# or C++. Anybody?

like image 506
AZDean Avatar asked Apr 04 '09 20:04

AZDean


People also ask

Can you define a parabola with 3 points?

Given three non collinear points, you can uniquely define a parabola of the form y=a(x+b)2+c which passes through the three points.

How do you find an equation with 3 points?

Use the standard form y=ax2+bx+c and the 3 points to write 3 equations with, a, b, and c as the variables and then solve for the variables.

How do you graph a parabola with given points?

To begin, we graph our first parabola by plotting points. Given a quadratic equation of the form y=ax2+bx+c, x is the independent variable and y is the dependent variable. Choose some values for x and then determine the corresponding y-values. Then plot the points and sketch the graph.


2 Answers

Thanks David, I converted your pseudocode to the following C# code:

public static void CalcParabolaVertex(int x1, int y1, int x2, int y2, int x3, int y3, out double xv, out double yv)
{
    double denom = (x1 - x2) * (x1 - x3) * (x2 - x3);
    double A     = (x3 * (y2 - y1) + x2 * (y1 - y3) + x1 * (y3 - y2)) / denom;
    double B     = (x3*x3 * (y1 - y2) + x2*x2 * (y3 - y1) + x1*x1 * (y2 - y3)) / denom;
    double C     = (x2 * x3 * (x2 - x3) * y1 + x3 * x1 * (x3 - x1) * y2 + x1 * x2 * (x1 - x2) * y3) / denom;

    xv = -B / (2*A);
    yv = C - B*B / (4*A);
}

This is what I wanted. A simple calculation of the parabola's vertex. I'll handle integer overflow later.

like image 103
AZDean Avatar answered Sep 29 '22 01:09

AZDean


This is really just a simple linear algebra problem, so you can do the calculation symbolically. When you substitute in the x and y values of your three points, you'll get three linear equations in three unknowns.

A x1^2 + B x1 + C = y1
A x2^2 + B x2 + C = y2
A x3^2 + B x3 + C = y3

The straightforward way to solve this is to invert the matrix

x1^2  x1  1
x2^2  x2  1
x3^2  x3  1

and multiply it by the vector

y1
y2
y3

The result of this is... okay, not exactly all that simple ;-) I did it in Mathematica, and here are the formulas in pseudocode:

denom = (x1 - x2)(x1 - x3)(x2 - x3)
A = (x3 * (y2 - y1) + x2 * (y1 - y3) + x1 * (y3 - y2)) / denom
B = (x3^2 * (y1 - y2) + x2^2 * (y3 - y1) + x1^2 * (y2 - y3)) / denom
C = (x2 * x3 * (x2 - x3) * y1 + x3 * x1 * (x3 - x1) * y2 + x1 * x2 * (x1 - x2) * y3) / denom

Alternatively, if you wanted to do the matrix math numerically, you'd typically turn to a linear algebra system (like ATLAS, though I'm not sure if it has C#/C++ bindings).

In any case, once you have the values of A, B, and C as calculated by these formulas, you just have to plug them into the expressions given in the question, -B / 2A and C - B^2/4A, to calculate the coordinates of the vertex.1

Note that if the original three points have coordinates that make denom a very large or very small number, doing the calculation directly might be susceptible to significant numerical error. In that case it might be better to modify it a bit, to avoid dividing by the denominators where they would cancel out anyway:

denom = (x1 - x2)(x1 - x3)(x2 - x3)
a = (x3 * (y2 - y1) + x2 * (y1 - y3) + x1 * (y3 - y2))
b = (x3^2 * (y1 - y2) + x2^2 * (y3 - y1) + x1^2 * (y2 - y3))
c = (x2 * x3 * (x2 - x3) * y1 + x3 * x1 * (x3 - x1) * y2 + x1 * x2 * (x1 - x2) * y3)

and then the coordinates of the vertex are -b / 2a and (c - b^2 / 4a) / denom. There are various other situations that might benefit from "tricks" like this, such as if A is very large or very small, or if C is nearly equal to B^2 / 4A so that their difference is very small, but I think those situations vary enough that a full discussion would be better left for case-by-case followup questions.

Converting all of this to code in the language of your choice is left as an exercise for the reader. (It should be pretty trivial in any language that uses standard infix operator syntax, e.g. as AZDean showed in C#.)


1In the initial version of the answer I thought this would be obvious, but it seems there are a lot of people who like having it mentioned explicitly.

like image 32
David Z Avatar answered Sep 29 '22 00:09

David Z