Domanda

Ho un'equazione di una curva parabolica che interseca un punto specifico, nel mio caso in cui l'utente ha fatto clic su un grafico.

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

Questo dà un grafico come questo:

curva parabolica

Ho anche una serie di segmenti di linea definita da coordinate iniziale e finale:

startX:Number, startY:Number, endX:Number, endY:Number

Ho bisogno di trovare se e dove questa curva interseca questi segmenti (A):

alt text

Se si tratta di alcun aiuto, startX è sempre < endX

ho la sensazione che c'è un modo abbastanza semplice per fare questo, ma io non so davvero cosa cercare, né sono molto ben versati nella "propria" la matematica, gli esempi di codice in modo effettivo sarebbe molto apprezzato .

UPDATE:

Ho il lavoro di intersezione, ma la mia soluzione mi dà la coordinata per la parte sbagliata della y.

La sostituzione mie coordinate bersaglio con A e B, rispettivamente, dà questa equazione per 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)

Questo è una risposta corretta, ma voglio la seconda variante possibile. Sono riuscito a correggere questo moltiplicando m con -1 prima del calcolo e fare lo stesso con il valore x le ultime dichiarazioni di calcolo, ma che si sente come un hack.

SOLUZIONE:

 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);
 }
È stato utile?

Soluzione

In alternativa, più esplicito ancora.

Se la curva parabolica è y(x)= A x2+ B x + C (Eq 1)

e la vostra linea è y(x) = m x + b (Eq 2)

Le due soluzioni possibili (+ e -) per x sono

x = ((-B + m +- Sqrt[4 A b + B^2 - 4 A C - 2 B m + m^2])/(2 A))   (Eq 3)

Si dovrebbe controllare se gli endpoint di settore (in x) contiene uno di questi due punti. Se lo fanno, basta sostituire le x corrispondenti nella y = m x + b equazione per ottenere la coordinata y per l'intersezione

Modifica>

Per ottenere l'ultima equazione hai appena detto che la "y" in eq 1 è pari al "y" in eq 2 (perché siete alla ricerca di un incrocio!). Che ti dà:

A x2+ B x + C = m x + b

e raggruppamento

A x2+ (B-m) x + (C-b) = 0

Che è un'equazione di secondo grado.

L'equazione 3 sono solo due possibili soluzioni per questo quadratica.

Modifica 2>

rileggendo il codice, sembra che la vostra parabola è definita da y(x) = A x2

dove
A = (target.y / (target.x)2)

Quindi nel tuo caso l'equazione 3 diventa semplicemente

 x = ((m +- Sqrt[4 A b + m^2])/(2 A))   (Eq 3b)  

HTH!

Altri suggerimenti

Prendere l'equazione per la curva e mettere la vostra linea in y = mx + b modulo. Risolvere per x e quindi determinare se X è tra le vostre punti iniziale e finale per voi segmento di linea.

Check out: http://mathcentral.uregina.ca/ QQ / database / QQ.09.03 / senthil1.html

stai facendo questo abbastanza spesso a desiderare un test separato per vedere se esiste un incrocio prima di poter realmente calcolare il punto di intersezione? In caso affermativo, considerare il fatto che la parabola è un insieme di livello per la funzione f (x, y) = y - (B * x * x) / (A * A) - in particolare, quello per cui f (x, y) = 0. Plug vostri due punti finali in f (x, y) - se hanno lo stesso segno, sono sullo stesso lato della parabola, mentre se hanno segni diversi, sono su lati diversi la parabola.

Ora, si potrebbe avere ancora un segmento che interseca la parabola due volte , e questo test non capito. Ma qualcosa nel modo in cui si sta definendo il problema mi fa sentire che forse questo è ok per la vostra applicazione.

In altre parole, è necessario Calulate l'equazione per ogni segmento di linea y = Ax + B confrontarlo con equazione della curva y = Cx^2 + Dx + E così Ax + B - Cx^2 - Dx - E = 0 e vedere se c'è una soluzione tra i valori startX e endX.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top