2012-02-08 23 views
7

Tôi có đường cong bậc hai được vẽ trên canvas html bằng cách sử dụng context.quadraticCurveTo(controlX, controlY, endX, endY);.Điểm trung tâm trên đường cong bậc hai html

Tôi có điểm điều khiển và điểm bắt đầu và điểm kết thúc, không nhất thiết phải nằm ngang với nhau.

Làm cách nào để tìm điểm trung tâm trên đường cong bằng các thông số này?

Thực ra tôi muốn đặt thẻ div vào điểm trung tâm này. Có cách giải quyết phương trình nào liên quan đến quá trình này không?

+0

Xin giải thích những gì bạn có ý nghĩa bởi "điểm kiểm soát" và "bắt đầu" và "kết thúc" điểm. –

+0

Điểm kiểm soát là điểm chịu trách nhiệm về hình dạng đường cong, điểm bắt đầu là điểm bắt đầu đường cong và điểm cuối là điểm kết thúc của đường cong. –

+0

Không có điểm duy nhất nào có thể chịu trách nhiệm về hình dạng của đường cong - hình dạng của đường cong được xác định bởi các giá trị a, b, c khi được viết dưới dạng chung. Điểm bắt đầu và kết thúc của bạn - chúng có nằm ngang với nhau không? Bạn có một phương trình bạn đang âm mưu? –

Trả lời

16

quadraticCurveTo vẽ quadratic Bézier curve.

Các công thức để tính toán tọa độ của một điểm tại bất kỳ vị trí nhất định (0-1) trên đường cong là

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 

nơi (x1, y1) là điểm khởi đầu, (x2, y2) là điểm điều khiển và (x3, y3) là điểm kết thúc.

Vì vậy, biến đó thành JavaScript, chúng ta kết thúc với một cái gì đó giống như

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

Nếu bạn vượt qua điểm bắt đầu, kết thúc và kiểm soát để getQuadraticCurvePoint ở đó, cùng với 0.5 cho vị trí nửa chừng, bạn sẽ nhận được một đối tượng với các tọa độ X và Y.

Disclaimer - Tôi đã không kiểm tra mã, do đó mileage của bạn có thể thay đổi, nhưng nó dường như đúng. ;)

EDIT: Tôi đã thử nghiệm mã ở đây trong một jsfiddle. http://jsfiddle.net/QA6VG/

0

Đây là trang mô tả phương trình bậc hai và giải pháp của nó là: wiki page. Và đây là hướng dẫn tốt về chủ đề, hoàn chỉnh với sơ đồ: tutorial

+0

Trang này tôi biết và tôi cũng đang xem nó nhưng tôi muốn tính toán điểm trung tâm bằng cách sử dụng javascript. Tôi không biết cách tìm điểm trung tâm. –

+0

Nếu điểm bắt đầu và điểm kết thúc của bạn ngang với nhau theo chiều ngang, thì tọa độ x của đường cong sẽ trực tiếp ở giữa (tức là) x_start + ((x_end - x_start)/2) và tọa độ y có thể được tìm thấy bằng cách thay thế giá trị x này vào phương trình ban đầu thay vì x và giải nó. Bạn có phương trình? –

+0

Đây là vấn đề thực sự của con người.Tôi có điểm bắt đầu và điểm kết thúc ngẫu nhiên –

0

Một cách có thể:

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

Và jsfiddle tương ứng: jsfiddle.net/pTccL/