2011-08-12 72 views

回答

3

拐角可以通過設置線帽爲圓形的。

ctx.lineCap = "round"

您還可以將貝塞爾曲線的整體線條,打造更順暢整條生產線,通過,該行的每個點P「,...,P」 N + 1 ,應用等式P' k =(k /(n + 1))P k-1 +(1-(k /(n + 1)))P k[注意:以及選擇指向您用P ň之間的角度設定的閾值時,也許申請貝塞爾曲線的平滑和P N + 1]

結合這兩種技術與標準箱模糊的線本身會給你一個更平滑的線條出現。

編輯

從我可以告訴,實際上是一個數字的方式來做到這一點 - 你用的是完全取決於你。我給你舉個例子,讓您決定:假設你有一個從開始點p(鼠標按下)到終點(鼠標鬆開)繪製的路徑p ñ。該路徑由子路徑(由連接點連接的點)組成。我們可以使用lineTo()和stroke()來正常繪製從p0到p1的上下文路徑。僅僅通過觀看控制檯輸出,子路徑加入的點就是mousemove事件觸發。按順序在數組中記錄這些點。

當然,如果我們得出這樣的背景下爲主,我們已經移除了問題,所以這應該是做一個緩衝上下文(額外的canvas元素,例如)。緩衝區被清除,並且我們使用定位點來計算曲線。 bezierCurveTo打印三次函數(B(T)=(1-T) P +3(1-T) P +3(1-t)的噸 P +噸 P ,叔∈ [0,1]。通過您的陣列步驟(認爲for循環)重新計算與這些點的線從P 更新曲線0至P 的n-3。(做快速頭數學,你可能需要考慮在這個端點。所有這一切都取決於它的電弧式使用)。

因此,讓我看看我是否可以做這件事...我沒有測試它,所以我保證bugginess。

// Assume: 
// bfr = buffer context. 
// ctx = main context. 
// md = boolean value for mousedown 
// pts = []; <-- already contains lp (below) at pts[0]; 
// We've also recorded Pm in associative array lp [last point] 
// Draw is fired on mousemove. Mousemove records a current point in associative array cp 
draw = function() { 
    if(md) { 
     bfr.beginPath(); 
     bfr.moveTo(lp.x-.5, lp.y-.5); 
     bfr.lineTo(cp.x-.5, cp.y-.5); 
     pts.push({cp.x, cp.y}); 
     bfr.stroke(); 
    } 
} 

// Optionally, you could make this function recursive. 
// This assumes that you want to estimate the curve based on the whole line. 
bezier = function(pts) { 
    ctx.beginPath(); 
    ctx.moveTo(pts[0].x, pts[0].y); 
    for(var i = 0; i < pts.length - 3; i++) { 
    ctx.bezierCurveTo(pts[i+1].x, pts[i+1].y, pts[i+2].x, pts[i+2].y, pts[i+3].x, pts[i+3].y); 
    } 
    ctx.stroke(); 
} 

再次,這就是我所看到的 - 別人可能有一個完全不同的,我敢肯定,更好的解釋。我試圖撕掉我已經完成的大量事情,並快速地將它們與一些新代碼放在一起,給你一些想法。

+0

關於lineCap作品的提示。謝謝。關於貝塞爾曲線......我如何去「應用」方程?我計算每個點P後,是否只使用lineTo?我找到了quadraticCurveTo函數和貝塞爾版本,但只有3或4個輸入點。我如何將貝塞爾曲線應用於整個畫筆描邊? – Homan

+0

我會寫一個自定義函數。選擇記錄到陣列的採樣點,應用曲線。您可以對'mousemove'點火的點進行採樣,確定三點之間的角度以檢查它是否對採樣點具有顯着差異,如果是,則將其標記,然後使用它來應用曲線。我會將標記點的數組傳遞給函數以執行評估。始終以'mousedown'和'mouseup'開頭,分別爲0和n + 1。 – stslavik

+0

假設用戶繪製一個快速圓,但採樣點分佈更像八角形的角。你建議使用某種自定義函數bezierLine(sample_points)來「彎曲」這條線嗎?我不瞭解該功能會發生什麼?函數是否通過計算每個像素座標來繪製每個像素?或者該函數是否採用Bezier(t)遍歷的t-step參數,在這種情況下,該函數最終仍然會使用lineTo繪製一條線,對嗎? – Homan