math - sacar - Cómo calcular el centro de una elipse por dos puntos y tamaños de radio
hallar la ecuacion de la elipse que pasa por un punto (4)
La pregunta intermedia es bastante fácil ... no es así. Calcula el centro de una elipse desde el cuadro delimitador (es decir, el centro del cuadro es el centro de la elipse, siempre que la elipse esté centrada en el recuadro).
Para su primera pregunta, miraría la forma polar de la ecuación de elipse, que está disponible en Wikipedia . También necesitarías calcular la excentricidad de la elipse.
O podría forzar brutales los valores del cuadro delimitador ... averiguar si un punto se encuentra en la elipse y coincide con el ángulo e iterar a través de cada punto en el cuadro delimitador.
Mientras trabajaba en la implementación de SVG para que Internet Explorer se basara en su propio formato VML, llegué a un problema de traducción de un arco elíptico SVG a un arco elíptico VML.
En VML un arco está dado por: dos ángulos para dos puntos en la elipse y longitudes de radios, en SVG un arco está dado por: dos pares de coordenadas para dos puntos en la elipse y tamaños de la caja límite de la elipse
Entonces, la pregunta es: Cómo expresar ángulos de dos puntos en elipse a dos pares de sus coordenadas. Una pregunta intermedia podría ser: Cómo encontrar el centro de una elipse por coordenadas de un par de puntos en su curva.
Actualización : Tengamos una condición previa que diga que una elipse normalmente se coloca (sus radios son paralelos al eje del sistema de coordenadas lineales), por lo tanto no se aplica rotación.
Actualización : Esta pregunta no está relacionada con el elemento svg: elipse, sino con el comando "a" de arco elíptico en svg: path element ( SVG Paths: comandos de curva elíptica de arco )
Una elipse no puede definirse solo por dos puntos. Incluso un círculo (una elipse revestida especial) se define por tres puntos.
Incluso con tres puntos, tendrías infinitas elipsis pasando por estos tres puntos (piensa: rotación).
Tenga en cuenta que un cuadro delimitador sugiere un centro para la elipse, y muy probablemente asuma que sus ejes mayor y menor son paralelos a los ejes x, y (o y, x).
Entonces la solución está aquí:
La fórmula parametrizada de una elipse:
x = x0 + a * cos(t) y = y0 + b * sin(t)
Pongamos las 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 elipse (x0 / y0) y dos ángulos t1, t2
Vamos a restar ecuaciones para deshacerte 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)
Vamos a reemplazar 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)
La división de la primera ecuación por segundo produce:
a1 = arctan(r1/r2)
Agregar este resultado a la primera ecuación da:
a2 = arcsin(r2 / cos(arctan(r1/r2)))
O, simple (usando composiciones de trigonometría y funciones 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 también las coordenadas del centro de eclipse.
El enlace de arco de curva elíptica que ha publicado incluye un enlace a las notas de implementación de arco elíptico .
Allí, encontrará las ecuaciones para la conversión de la parametrización del punto final al centro .
Aquí está mi implementación de JavaScript de esas ecuaciones, tomadas de una demostración interactiva de rutas de arco elípticas , usando Sylvester.js para realizar los cálculos de matriz y vector.
// 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);