Saltar al contenido

Cómo calcular el vértice de una parábola dados tres puntos

Contamos con tu apoyo para compartir nuestras secciones acerca de las ciencias informáticas.

Solución:

Gracias David, convertí tu pseudocódigo al siguiente código C#:

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);

Esto es lo que quería. Un cálculo simple del vértice de la parábola. Me ocuparé del desbordamiento de enteros más tarde.

Este es realmente un simple problema de álgebra lineal, por lo que puede hacer el cálculo simbólicamente. Cuando sustituyas los valores x e y de tus tres puntos, obtendrás tres ecuaciones lineales con tres incógnitas.

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

La forma sencilla de resolver esto es invertir la matriz

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

y lo multiplicamos por el vector

y1
y2
y3

El resultado de esto es… bueno, no es tan simple 😉 Lo hice en Mathematica, y aquí están las fórmulas en pseudocódigo:

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

Alternativamente, si quisiera hacer la matriz matemática numéricamente, normalmente recurriría a un sistema de álgebra lineal (como ATLAS, aunque no estoy seguro de si tiene enlaces C#/C++).

En cualquier caso, una vez que tenga los valores de A, By C según lo calculado por estas fórmulas, solo tiene que reemplazarlas en las expresiones dadas en la pregunta, -B / 2A y C - B^2/4Apara calcular las coordenadas del vértice.1

Tenga en cuenta que si los tres puntos originales tienen coordenadas que hacen denom un número muy grande o muy pequeño, hacer el cálculo directamente puede ser susceptible a un error numérico significativo. En ese caso, sería mejor modificarlo un poco, para evitar dividir por los denominadores donde se cancelarían de todos modos:

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)

y entonces las coordenadas del vértice son -b / 2a y (c - b^2 / 4a) / denom. Hay varias otras situaciones que podrían beneficiarse de “trucos” como este, como si A es muy grande o muy pequeño, o si C es casi igual a B^2 / 4A por lo que su diferencia es muy pequeña, pero creo que esas situaciones varían lo suficiente como para dejar una discusión completa para preguntas de seguimiento caso por caso.

Convertir todo esto en código en el idioma de su elección se deja como ejercicio para el lector. (Debería ser bastante trivial en cualquier idioma que use la sintaxis estándar del operador infijo, por ejemplo, como AZDean mostró en C#).


1En la versión inicial de la respuesta, pensé que esto sería obvio, pero parece que hay muchas personas a las que les gusta que se mencione explícitamente.

Obtienes las siguientes tres ecuaciones por sustitución directa:

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

Puede resolver esto observando que esto es equivalente al producto de matrices:

[x1^2 x1 1] [A]   [y1]
|x2^2 x2 1|*|B| = |y2|
[x3^2 x3 1] [C]   [y3]

Entonces puedes obtener A, B y C invirtiendo la matriz y multiplicando el inverso con el vector de la derecha.

Veo que mientras publicaba esto, John Rasch se ha vinculado a un tutorial que profundiza más en la resolución de la ecuación matricial, por lo que puede seguir esas instrucciones para obtener la respuesta. Invertir una matriz de 3×3 es bastante fácil, por lo que no debería ser demasiado difícil.

Ten en cuenta difundir esta sección si si solucionó tu problema.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *