2012-02-08 3 views
7

У меня квадратная кривая, нарисованная на холсте html, с использованием context.quadraticCurveTo(controlX, controlY, endX, endY);.Центральная точка на html квадратичная кривая

У меня есть контрольная точка и начальная и конечная точки, которые не обязательно выравниваются друг с другом по горизонтали.

Как найти центральную точку на кривой, используя эти параметры?

На самом деле я хочу поместить тег div в эту центральную точку. Есть ли какое-либо решение уравнения, участвующее в этом процессе?

+0

Пожалуйста, объясните, что вы имеете в виду под "контрольной точки" и "начиная" и "окончание" точек. –

+0

Контрольная точка - это точка, которая отвечает за форму кривой, начальная точка - это точка, где начинается кривая, а конечный pont - это тот, где заканчивается кривая. –

+0

Ни одна точка не может быть ответственна за форму кривой - форма кривой определяется значениями a, b, c при записи в общем виде. Ваши начальные и конечные точки - они горизонтально расположены друг с другом? У вас есть уравнение, которое вы рисуете? –

ответ

16

quadraticCurveTo рисует quadratic Bézier curve.

Формулы для вычисления координат точки, в любом заданном положении (от 0 до 1) на кривой являются

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 

где (x1, y1) является отправной точкой, (х2, у2) является контрольной точкой, а (x3, y3) является конечной точкой.

Так, поворачиваясь, что в JavaScript, мы в конечном итоге с чем-то вроде

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

Если вы передаете начало, конец и контрольные точки getQuadraticCurvePoint там, наряду с 0.5 на полпути позиции, вы должны получить объект с координатами X и Y.

Отказ от ответственности - я не тестировал код, поэтому ваш пробег может отличаться, но это кажется справа. ;)

EDIT: Я проверил код здесь в jsfiddle. http://jsfiddle.net/QA6VG/

0

Вот страница, описывающая квадратичное уравнение и его решение: wiki page. А вот хороший учебник по этому вопросу, в комплекте с диаграммами: tutorial

+0

Эта страница, которую я знаю, а также я смотрю на нее, но я хочу рассчитать точку центра, используя javascript. Я не знаю, как найти центр. –

+0

Если ваши начальные и конечные точки расположены горизонтально друг с другом горизонтально, координата x кривой будет находиться непосредственно в середине (т.е.) x_start + ((x_end - x_start)/2), а координату y можно найти, заменив это значение x в исходное уравнение вместо x и его решение. У вас есть уравнение? –

+0

Это настоящий человек проблемы.У меня есть случайные начальные и конечные точки –

0

Возможный способ:

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

И соответствующая jsfiddle: jsfiddle.net/pTccL/

Смежные вопросы