2012-02-08 10 views
7

Ho una curva quadratica disegnata su tela html utilizzando context.quadraticCurveTo(controlX, controlY, endX, endY);.Punto centrale sulla curva quadratica html

Ho il punto di controllo e i punti di inizio e fine, che non sono necessariamente orizzontali tra loro.

Come posso trovare il punto centrale sulla curva utilizzando questi parametri?

In realtà voglio mettere un tag div su questo punto centrale. C'è qualche soluzione all'equazione coinvolta in questo processo?

+0

Si prega di spiegare che cosa si intende per "punto di controllo" e "a partire" e punti "fine". –

+0

Il punto di controllo è un punto responsabile della forma della curva, il punto iniziale è il punto in cui inizia la curva e il punto finale è quello in cui termina la curva. –

+0

Nessun singolo punto può essere responsabile della forma della curva - la forma della curva è definita dai valori di a, b, c quando viene scritta in forma generale. I tuoi punti di partenza e di arrivo - sono a livello l'uno dell'altro in orizzontale? Hai un'equazione che stai progettando? –

risposta

16

quadraticCurveTo disegna un quadratic Bézier curve.

Le formule per calcolare le coordinate di un punto in una data posizione (da 0 a 1) sulla curva sono

x(t) = (1-t)^2 * x1 + 2 * (1-t) * t * x2 + t^2 * x3 
y(t) = (1-t)^2 * y1 + 2 * (1-t) * t * y2 + t^2 * y3 

dove (x1, y1) è il punto di partenza, (x2, y2) è il punto di controllo e (x3, y3) è il punto finale.

Quindi, svolta che in JavaScript, si finisce con qualcosa come

function _getQBezierValue(t, p1, p2, p3) { 
    var iT = 1 - t; 
    return iT * iT * p1 + 2 * iT * t * p2 + t * t * p3; 
} 

function getQuadraticCurvePoint(startX, startY, cpX, cpY, endX, endY, position) { 
    return { 
     x: _getQBezierValue(position, startX, cpX, endX), 
     y: _getQBezierValue(position, startY, cpY, endY) 
    }; 
} 

Se si passa i punti di inizio, di fine e di controllo per getQuadraticCurvePoint lì, insieme con 0.5 per la posizione a metà strada, si dovrebbe ottenere un oggetto con le coordinate X e Y.

Disclaimer - Non ho eseguito il test del codice, quindi il tuo chilometraggio può variare, ma è sembra a destra. ;)

MODIFICA: ho testato il codice qui in un jsfiddle. http://jsfiddle.net/QA6VG/

0

Ecco una pagina che descrive l'equazione quadratica e la sua soluzione: wiki page. Ed ecco un buon tutorial su questo argomento, completa di diagrammi: tutorial

+0

Questa pagina lo conosco e anche io la sto guardando ma voglio calcolare il punto centrale usando javascript. Non so come trovare il punto centrale. –

+0

Se i punti iniziale e finale sono orizzontali, la coordinata x della curva sarà direttamente al centro (cioè) x_start + ((x_end - x_start)/2) e la coordinata y può essere trovata sostituendo questo valore x nell'equazione originale invece di x e la risoluzione. Hai l'equazione? –

+0

Questo è il vero problema dell'uomo.Ho punti di inizio e fine casuali –

0

Un modo possibile:

// compute coordinates of the middle point of a quadratic Bezier curve 
// need two functions: quadraticBezierCurvePoint and quadraticBezierCurvesMiddle 

function quadraticBezierCurvePoint(t, c) { 
    // compute relative coordinates of a point on the curve using t and c 
    // t is a number between 0 and 1 
    // c is an array of 3 points: 
    //  the initial point of the curve (always (0,0)) 
    //  the "handle" point of the curve 
    //  the final point of the curve 
    var t1, t1_2a, t1_2b, t1_2c; 
    t1 = 1 - t; 
    t1_2a = t1 * t1; 
    t1_2b = (2 * t) * t1; 
    t1_2c = t * t; 
    return { 
    x: (c[0].x * t1_2a) + (t1_2b * c[1].x) + (t1_2c * c[2].x), 
    y: (c[0].y * t1_2a) + (t1_2b * c[1].y) + (t1_2c * c[2].y) 
    }; 
} 

function quadraticBezierCurvesMiddle(m, c) { 
    var k, km = 1000, 
    km2 = (km >> 1), 
    len = 0, 
    len2, x, y, a = new Array(km + 1); 
    // compute curve lengths from start point to any point 
    // store relative point coordinates and corresponding length in array a 
    for (k = 0; k <= km; k++) { 
    a[k] = { 
     pt: quadraticBezierCurvePoint(k/km, c), 
     len: 0 
    }; 
    if (k > 0) { 
     x = a[k].pt.x - a[k - 1].pt.x; 
     y = a[k].pt.y - a[k - 1].pt.y; 
     a[k].len = a[k - 1].len + Math.sqrt(x * x + y * y); 
    } 
    } 
    // retrieve the point which is at a distance of half the whole curve length from start point 
    // most of the time, this point is not the one at indice km2 in array a, but it is near it 
    len2 = a[km].len/2; 
    if (a[km2].len > len2) 
    for (k = km2; k >= 0; k--) { 
     if (len2 >= a[k].len) break; 
    } else 
    for (k = km2; k <= km; k++) { 
     if (len2 <= a[k].len) break; 
    } 
    // return absolute coordinates of the point 
    return { 
    x: Math.round((a[k].pt.x + m.x) * 100)/100, 
    y: Math.round((a[k].pt.y + m.y) * 100)/100 
    }; 
} 

e il corrispondente jsfiddle: jsfiddle.net/pTccL/