2012-02-08 16 views
7

context.quadraticCurveTo(controlX, controlY, endX, endY);を使用してhtmlキャンバスに2次曲線を描いています。html二次曲線の中心点

私は制御点と開始点と終了点を持っていますが、これらは必ずしも水平になる必要はありません。

これらのパラメータを使用して曲線上の中心点を見つける方法はありますか?

実際には、この中心点にdivタグを挿入します。 このプロセスに関係する方程式の解はありますか?

+0

あなたは "コントロールポイント" と "開始" と "終了" のポイントで何を意味するか説明してください。 –

+0

制御点は曲線の形状を担当する点であり、開始点は曲線が始まる点であり、終点は曲線が終わる点である。 –

+0

単一の点では曲線の形状に責任を負うことはできません。曲線の形状は一般的な形で記述されたときにa、b、cの値で定義されます。あなたの出発点と終点 - 彼らは水平にお互いのレベルですか?プロットしている式がありますか? –

答えて

16

quadraticCurveToquadratic Bézier curveを描く: そして、ここでは図との完全な主題に良いチュートリアル、です。曲線上(0〜1)任意の位置での点の座標を計算する

式が(X1、Y1)を(X2、Y2)、出発点である

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 

ありますは制御点、(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) 
    }; 
} 

あなたが途中位置のための0.5とともに、そこgetQuadraticCurvePointに開始、終了とコントロールポイントを通過した場合のようなもので終わる、あなたが取得する必要がありますオブジェクトはX座標とY座標を持ちます。

免責事項 - 私はコードをテストしなかったため、あなたの走行距離は異なる場合がありますが、と思われます。 ;)

編集:私はここでコードをjsfiddleでテストしました。 http://jsfiddle.net/QA6VG/

0

ここでは、2次方程式とその解を説明するページです:wiki pagetutorial

+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/

関連する問題