2012-02-08 10 views
7

Mam kwadratową krzywą narysowaną na kanwie html przy użyciu context.quadraticCurveTo(controlX, controlY, endX, endY);.Punkt środkowy na krzywej kwadratowej html

Posiadam punkt kontrolny oraz punkty początkowe i końcowe, które niekoniecznie leżą poziomo w stosunku do siebie.

Jak mogę znaleźć punkt środkowy na krzywej, używając tych parametrów?

Właściwie chcę umieścić znacznik div w tym punkcie środkowym. Czy w procesie tym stosowane jest rozwiązywanie równań?

+0

Proszę wyjaśnić, co to znaczy "punktu kontrolnego" i "startu" i punktów "ending". –

+0

Punkt kontrolny jest punktem, który odpowiada za kształt krzywej, punktem początkowym jest punkt, w którym rozpoczyna się krzywa, a koniec końcowy to punkt, w którym kończy się krzywa. –

+0

Żaden pojedynczy punkt nie może być odpowiedzialny za kształt krzywej - kształt krzywej jest zdefiniowany przez wartości a, b, c, gdy jest zapisany w formie ogólnej. Twoje początkowe i końcowe punkty - czy poziomują się poziomo? Czy masz równanie, które knujesz? –

Odpowiedz

16

quadraticCurveTo rysuje quadratic Bézier curve.

Wzory do obliczania współrzędnych punktu w określonym położeniu (od 0 do 1) na krzywej są

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 

gdzie (x1, y1) jest punktem wyjścia (x2, y2) jest punktem kontrolnym i (x3, y3) jest punktem końcowym.

Tak, obracając że w JavaScripcie, możemy skończyć z czymś takim

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

Jeśli przekazać początek, koniec i kontroli punktów getQuadraticCurvePoint tam, wraz z 0.5 na stanowisko połowy, należy uzyskać obiekt ze współrzędnymi X i Y.

Zrzeczenie się - Nie testowałem kodu, więc Twój przebieg może się różnić, ale wygląda na prawo. ;)

EDYCJA: Testowałem kod tutaj w jsfiddle. http://jsfiddle.net/QA6VG/

0

Oto strona opisująca równanie kwadratowe i jego rozwiązanie: wiki page. I tu jest dobry tutorial na ten temat, wraz ze schematami: tutorial

+0

Ta strona Wiem, a także patrzę na to, ale chcę obliczyć punkt środkowy za pomocą javascript. Nie wiem, jak znaleźć punkt centralny. –

+0

Jeśli punkty początkowe i końcowe są wyrównane poziomo, to współrzędna x krzywej będzie znajdować się bezpośrednio w środku (tj.) X_start + ((x_end - x_start)/2), a współrzędna y można znaleźć przez podstawienie wartość x do pierwotnego równania zamiast x i rozwiązanie. Czy masz równanie? –

+0

To jest prawdziwy problem.Mam losowy punkt początkowy i końcowy –

0

Możliwym sposobem:

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

i odpowiadająca jsfiddle: jsfiddle.net/pTccL/

Powiązane problemy