Canvas2d不支持任意Hermite樣條曲線,但它確實支持三次Bezier曲線,並且由於三次Beziers是二階Hermite曲線,我們可以在數據和貝塞爾曲線之間自由轉換。
做到這一點的數學可以在這個Primer on Bezier curves找到了,並專門針對這個問題,我們可以轉換埃爾米特點有序[P1,D1,P2,D2]爲:
注意,值是曲線張力並控制每個點處的曲率順序(張力越高,曲線上點附近的曲率變化率越高),在這種情況下僅爲1
。
(沒有張力值,您的四個座標實際上在平面上定義了一個沙漏六角形區域,而不是單個曲線,因爲方向矢量不能保證是真正的切線;只是表示行進方向的矢量。這些值定義的區域由一邊的{start,end}行界定,在開始和結束時沿着行進方向具有無限延伸的邊界)。
所以與,可以繪製在畫布上的畫布上的任何埃爾米特曲線,使用用於三次貝塞爾曲線Canvas2d API:
// Hermite data
var p1 = ..., d1 = ..., p2 = ..., d2 = ...;
var cmpoints = [p1.x, p1.y, d1.x, d1.y, p2.x, p2.y, d2.x, d2.y];
// Bezier data
var tension = 1;
var tensionFactor = 2 * tension;
var bpoints = [
p1.x,
p1.y,
p1.x + d1.x/tensionFactor,
p1.y + d1.y/tensionFactor,
p2.x - d2.x/tensionFactor,
p2.y - d2.y/tensionFactor,
p2.x,
p2.y
]
// Draw code (where we assume you already
// have your canvas context as "ctx")
ctx.beginPath();
ctx.moveTo.apply(bpoints.slice(0,2));
ctx.bezierCurveTo.apply(bpoints.slice(2);
ctx.stroke();
請提供一個[最小,完整,可驗證](http://stackoverflow.com/help/mcve)嘗試,所以我們可以嘗試解決你的問題,並解釋爲什麼你自己的嘗試失敗 - 這樣你可以學習一些對你未來發展有用的東西,並且得到這個單一問題的答案。 –
這[小提琴](http://jsfiddle.net/jmchen/m9k8qn0v/1/)可能會有所提示。 –
[這裏](http://stackoverflow.com/a/15528789/1693593)是一個Catmull-Rom實現與張力(又名基數樣條)。 – K3N