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:

curva parabólica

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

text alt

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);
 }
¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top