Saltar al contenido

Cómo calcular el centro de una elipse por dos puntos y tamaños de radio

Posterior a consultar con expertos en la materia, programadores de deferentes áreas y profesores dimos con la solución al dilema y la plasmamos en este post.

Solución:

Así que la solución está aquí:

La fórmula parametrizada de una elipse:

x = x0 + a * cos(t)
y = y0 + b * sin(t)

Pongámosle coordenadas conocidas de dos puntos:

x1 = x0 + a * cos(t1)
x2 = x0 + a * cos(t2)
y1 = y0 + b * sin(t1)
y2 = y0 + b * sin(t2)

Ahora tenemos un sistema de ecuaciones con 4 variables: centro de la elipse (x0/y0) y dos ángulos t1, t2

Vamos a restar ecuaciones para deshacernos de las coordenadas centrales:

x1 - x2 = a * (cos(t1) - cos(t2))
y1 - y2 = b * (sin(t1) - sin(t2))

Esto se puede reescribir (con fórmulas de identidades de producto a suma) como:

(x1 - x2) / (2 * a) = sin((t1 + t2) / 2) * sin((t1 - t2) / 2)
(y2 - y1) / (2 * b) = cos((t1 + t2) / 2) * sin((t1 - t2) / 2)

Reemplacemos algunas de las ecuaciones:

r1: (x1 - x2) / (2 * a)
r2: (y2 - y1) / (2 * b)
a1: (t1 + t2) / 2
a2: (t1 - t2) / 2

Entonces obtenemos un sistema de ecuaciones simples:

r1 = sin(a1) * sin(a2)
r2 = cos(a1) * sin(a2)

Dividiendo la primera ecuación por la segunda se obtiene:

a1 = arctan(r1/r2)

Sumando este resultado a la primera ecuación se obtiene:

a2 = arcsin(r2 / cos(arctan(r1/r2)))

O, simple (usando composiciones de funciones trigonométricas y trigonométricas inversas):

a2 = arcsin(r2 / (1 / sqrt(1 + (r1/r2)^2)))

o incluso más simple:

a2 = arcsin(sqrt(r1^2 + r2^2))

Ahora, el sistema inicial de cuatro ecuaciones se puede resolver con facilidad y se pueden encontrar todos los ángulos, así como las coordenadas del centro del eclipse.

El enlace del arco de curva elíptica que publicó incluye un enlace a las notas de implementación del arco elíptico.

Allí encontrará las ecuaciones para la conversión de punto final a parametrización central.

Aquí está mi implementación de JavaScript de esas ecuaciones, tomada de una demostración interactiva de trayectorias de arco elípticas, utilizando Sylvester.js para realizar los cálculos de matrices y vectores.

// Calculate the centre of the ellipse
// Based on http://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpointToCenter
var x1 = 150;  // Starting x-point of the arc
var y1 = 150;  // Starting y-point of the arc
var x2 = 400;  // End x-point of the arc
var y2 = 300;  // End y-point of the arc
var fA = 1;    // Large arc flag
var fS = 1;    // Sweep flag
var rx = 100;  // Horizontal radius of ellipse
var ry =  50;  // Vertical radius of ellipse
var phi = 0;   // Angle between co-ord system and ellipse x-axes

var Cx, Cy;

// Step 1: Compute (x1′, y1′)
var M = $M([
               [ Math.cos(phi), Math.sin(phi)],
               [-Math.sin(phi), Math.cos(phi)]
            ]);
var V = $V( [ (x1-x2)/2, (y1-y2)/2 ] );
var P = M.multiply(V);

var x1p = P.e(1);  // x1 prime
var y1p = P.e(2);  // y1 prime


// Ensure radii are large enough
// Based on http://www.w3.org/TR/SVG/implnote.html#ArcOutOfRangeParameters
// Step (a): Ensure radii are non-zero
// Step (b): Ensure radii are positive
rx = Math.abs(rx);
ry = Math.abs(ry);
// Step (c): Ensure radii are large enough
var lambda = ( (x1p * x1p) / (rx * rx) ) + ( (y1p * y1p) / (ry * ry) );
if(lambda > 1)

    rx = Math.sqrt(lambda) * rx;
    ry = Math.sqrt(lambda) * ry;



// Step 2: Compute (cx′, cy′)
var sign = (fA == fS)? -1 : 1;
// Bit of a hack, as presumably rounding errors were making his negative inside the square root!
if((( (rx*rx*ry*ry) - (rx*rx*y1p*y1p) - (ry*ry*x1p*x1p) ) / ( (rx*rx*y1p*y1p) + (ry*ry*x1p*x1p) )) < 1e-7)
    var co = 0;
else
    var co = sign * Math.sqrt( ( (rx*rx*ry*ry) - (rx*rx*y1p*y1p) - (ry*ry*x1p*x1p) ) / ( (rx*rx*y1p*y1p) + (ry*ry*x1p*x1p) ) );
var V = $V( [rx*y1p/ry, -ry*x1p/rx] );
var Cp = V.multiply(co);

// Step 3: Compute (cx, cy) from (cx′, cy′)
var M = $M([
               [ Math.cos(phi), -Math.sin(phi)],
               [ Math.sin(phi),  Math.cos(phi)]
            ]);
var V = $V( [ (x1+x2)/2, (y1+y2)/2 ] );
var C = M.multiply(Cp).add(V);

Cx = C.e(1);
Cy = C.e(2);

Una elipse no puede ser definida por solo dos puntos. Incluso un círculo (una elipse encajonada especial) está definido por tres puntos.

Incluso con tres puntos, tendrías elipses infinitas pasando por estos tres puntos (piensa: rotación).

Tenga en cuenta que un cuadro delimitador sugiere un centro para la elipse y lo más probable es que suponga que sus ejes mayor y menor son paralelos a los ejes x,y (o y,x).

Sección de Reseñas y Valoraciones

Al final de la artículo puedes encontrar las explicaciones de otros gestores de proyectos, tú incluso tienes el poder mostrar el tuyo si te gusta.

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



Utiliza Nuestro Buscador

Deja una respuesta

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