Intersección de la curva parabólica y segmento de línea
-
25-09-2019 - |
Pregunta
Tengo una ecuación para una curva parabólica que intersecta un punto especificado, en mi caso donde el usuario hace clic en un gráfico.
// this would typically be mouse coords on the graph
var _target:Point = new Point(100, 50);
public static function plot(x:Number, target:Point):Number{
return (x * x) / target.x * (target.y / target.x);
}
Esto da un gráfico como este:
También tiene una serie de segmentos de línea definido por las coordenadas de inicio y fin:
startX:Number, startY:Number, endX:Number, endY:Number
Necesito encontrar si, y en que la curva cruza estos segmentos (A):
Si te sirve de ayuda, startX
es siempre < endX
Me da la impresión de que hay una manera bastante sencillo de hacer esto, pero no se sabe muy bien qué buscar, ni soy muy versado en matemáticas "adecuada", ejemplos de código de modo real sería muy apreciada .
ACTUALIZACIÓN:
Tengo la intersección de trabajo, pero mi solución me da la coordenada para el lado equivocado del eje y.
Sustitución de mis coords diana con A y B respectivamente, da esta ecuación para la trama:
(x * x) / A * (B/A)
// this simplifies down to:
(B * x * x) / (A * A)
// which i am the equating to the line's equation
(B * x * x) / (A * A) = m * x + b
// i run this through wolfram alpha (because i have no idea what i'm doing) and get:
(A * A * m - A * Math.sqrt(A * A * m * m + 4 * b * B)) / (2 * B)
Este es una respuesta correcta, pero yo quiero la segunda variación posible. Me las he arreglado para corregir esto multiplicando m con -1 antes del cálculo y hacer lo mismo con el valor x las últimas vueltas de cálculo, pero que se siente como un truco.
SOLUCIÓN:
public static function intersectsSegment(targetX:Number, targetY:Number, startX:Number, startY:Number, endX:Number, endY:Number):Point {
// slope of the line
var m:Number = (endY - startY) / (endX - startX);
// where the line intersects the y-axis
var b:Number = startY - startX * m;
// solve the two variatons of the equation, we may need both
var ix1:Number = solve(targetX, targetY, m, b);
var ix2:Number = solveInverse(targetX, targetY, m, b);
var intersection1:Point;
var intersection2:Point;
// if the intersection is outside the line segment startX/endX it's discarded
if (ix1 > startX && ix1 < endX) intersection1 = new Point(ix1, plot(ix1, targetX, targetY));
if (ix2 > startX && ix2 < endX) intersection2 = new Point(ix2, plot(ix2, targetX, targetY));
// somewhat fiddly code to return the smallest set intersection
if (intersection1 && intersection2) {
// return the intersection with the smaller x value
return intersection1.x < intersection2.x ? intersection1 : intersection2;
} else if (intersection1) {
return intersection1;
}
// this effectively means that we return intersection2 or if that's unset, null
return intersection2;
}
private static function solve(A:Number, B:Number, m:Number, b:Number):Number {
return (m + Math.sqrt(4 * (B / (A * A)) * b + m * m)) / (2 * (B / (A * A)));
}
private static function solveInverse(A:Number, B:Number, m:Number, b:Number):Number {
return (m - Math.sqrt(4 * (B / (A * A)) * b + m * m)) / (2 * (B / (A * A)));
}
public static function plot(x:Number, targetX:Number, targetY:Number):Number{
return (targetY * x * x) / (targetX * targetX);
}
Solución
O, más explícita todavía.
Si su curva parabólica es
y(x)= A x2+ B x + C (Eq 1)
y su línea está
y(x) = m x + b (Eq 2)
Las dos soluciones posibles (+ y -) para x son
x = ((-B + m +- Sqrt[4 A b + B^2 - 4 A C - 2 B m + m^2])/(2 A)) (Eq 3)
Se debe comprobar si sus puntos extremos del segmento (en X) contiene cualquiera de estos dos puntos. Si lo hacen, simplemente sustituyen a los x correspondientes en Y = m x + b ecuación para obtener la coordenada y para la intersección
Editar>
Para obtener la última ecuación que acaba de decir que la "y" en la ecuación 1 es igual a la "y" en la ecuación 2 (debido a que busca una intersección!). Eso le da:
A x2+ B x + C = m x + b
y reagrupamiento
A x2+ (B-m) x + (C-b) = 0
Lo cual es una ecuación de segundo grado.
Ecuación 3 son sólo las dos soluciones posibles para este cuadrática.
Editar 2>
re-lectura de su código, parece que su parábola se define por
y(x) = A x2
donde
A = (target.y / (target.x)2)
Así que en su caso la ecuación 3 se convierte simplemente
x = ((m +- Sqrt[4 A b + m^2])/(2 A)) (Eq 3b)
HTH!
Otros consejos
Tome la ecuación de la curva y poner su línea en y = mx + b formulario. Resolver para x y luego determinar si X está entre sus puntos de inicio y fin para el que la línea segmento.
Salida: http://mathcentral.uregina.ca/ QQ / base de datos / QQ.09.03 / senthil1.html
¿Estás haciendo esto a menudo suficiente para desear una prueba independiente para ver si existe una intersección antes de que realmente calcular el punto de intersección? Si es así, considerar el hecho de que su parábola es un conjunto de nivel para la función f (x, y) = y - (B * x * x) / (A * A) - específicamente, el uno para el cual f (x, y) = 0. Plug sus dos extremos en f (x, y) - si tienen el mismo signo, están en el mismo lado de la parábola, mientras que si tienen signos diferentes, que están en diferentes lados de la parábola.
Ahora, todavía podría tener un segmento que se cruza con la parábola dos veces , y esta prueba no se enganche eso. Pero algo en la forma en que está definiendo el problema me hace sentir que tal vez eso está bien para su aplicación.
En otras palabras, es necesario Calulate la ecuación para cada segmento de línea y = Ax + B
compararla con la curva de ecuación y = Cx^2 + Dx + E
por lo Ax + B - Cx^2 - Dx - E = 0
y ver si hay una solución entre los valores startX
y endX
.