2012-02-08 18 views
7

Tengo una curva cuadrática dibujada en un lienzo html usando context.quadraticCurveTo(controlX, controlY, endX, endY);.Punto central en la curva cuadrática html

Tengo el punto de control y los puntos de inicio y fin, que no están necesariamente nivelados entre sí horizontalmente.

¿Cómo puedo encontrar el punto central de la curva con estos parámetros?

En realidad, quiero poner una etiqueta div en este punto central. ¿Hay alguna solución de ecuación involucrada en este proceso?

+0

explicar qué quiere decir con "punto de control" y "final" puntos "de partida" y. –

+0

El punto de control es un punto que es responsable de la forma de la curva, el punto de inicio es el punto donde comienza la curva y el extremo final es uno donde termina la curva. –

+0

Ningún punto en particular puede ser responsable de la forma de la curva: la forma de la curva se define mediante los valores de a, b, c cuando se escribe en forma general. Sus puntos de inicio y final: ¿están nivelados entre sí horizontalmente? ¿Tienes una ecuación que estás tramando? –

Respuesta

16

quadraticCurveTo dibuja un quadratic Bézier curve.

Las fórmulas para calcular las coordenadas de un punto en cualquier posición dada (de 0 a 1) en la curva son

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 

donde (x1, y1) es el punto de partida, (x2, y2) es el punto de control y (x3, y3) es el punto final.

Así, convertirla en JavaScript, terminamos con algo como

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

Si sale de los puntos de inicio, final y de control a getQuadraticCurvePoint allí, junto con 0.5 para la posición a mitad de camino, usted debe tener una objeto con las coordenadas X e Y.

Descargo de responsabilidad - No he probado el código, por lo que su kilometraje puede variar, pero parece derecho. ;)

EDITAR: He probado el código aquí en jsfiddle. http://jsfiddle.net/QA6VG/

0

Aquí hay una página que describe la ecuación cuadrática y su solución: wiki page. Y aquí es un buen tutorial sobre el tema, con diagramas: tutorial

+0

Esta página la conozco y también la estoy buscando, pero quiero calcular el punto central usando javascript. No sé cómo encontrar el punto central. –

+0

Si sus puntos inicial y final están nivelados entre sí horizontalmente, entonces la coordenada x de la curva estará directamente en el centro (es decir) x_start + ((x_end - x_start)/2) y la coordenada y se puede encontrar sustituyendo este valor x en la ecuación original en lugar de xy resolverlo. ¿Tienes la ecuación? –

+0

Este es el hombre problema real.Tengo puntos de inicio y fin aleatorios –

0

Una forma posible:

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

Y el jsFiddle correspondiente: jsfiddle.net/pTccL/

Cuestiones relacionadas