2011-10-25 113 views
4

到目前爲止,流暢線條上的線條都不是正確的。用畫布繪製流暢的線條

how to draw smooth curve through N points using javascript HTML5 canvas?

Smooth user drawn lines in canvas

兩個結果在鋸齒線。平滑我的意思是使用x,y點作爲控制點使線條平滑。該線不需要經過這些點。它只需要繪製一條平滑的線,給出n個點。

基本上我記錄每一個線段,然後當用戶鼠標,它會平滑的線。

我已經嘗試過使用bezierCurveTo自己的方法,但只能平滑每個其他點,然後連接點仍然很苛刻。互聯網似乎認爲我在找的是B樣條曲線。我嘗試應用線性代數矩陣來解決這個問題,但是我失敗了。

這是我能得到的最好的曲線,(圖片)。紅色的線條是「平滑」線條,因爲您可以看到它平滑所有其他點,但不是連續的。這是使用代碼

how to draw smooth curve through N points using javascript HTML5 canvas?

我的代碼做同樣的事情

http://www.square-bracket.com/images/smoothlines.png

感謝您的幫助!

回答

3

您需要保持線條下方的點相同的切線。檢查http://jsfiddle.net/FHKuf/4/

編輯:

對不起,剛剛注意到你今天的評論。碰巧正在測試相關的東西並記住你的問題。它發生在過去我寫了一些代碼來插入一些行。它被稱爲Catmull-Rom(我只是一個參考,我googleed)它通過中間控制點。我確實已將代碼更改爲我的測試,並認爲您可能有一些用處。請參閱http://jsfiddle.net/FHKuf/6/

+0

這是非常接近。但是這些點上的曲線在這條線的對面彎曲。所以它現在是一條波浪線。生病看看是否可以操縱這是正確的,除非你知道爲什麼這樣做。謝謝! –

+0

這是因爲Catmull-Rom樣條曲線不插入段中的第一個和最後一個點,並且我在控制點列表的開始和結束處添加了點,以便繪製它們。嘗試玩像http://jsfiddle.net/FHKuf/54/ – Prusse

+0

這是一個古老的問題。我偶然發現一個名爲[Smooth的圖書館。JS](https://github.com/osuushi/Smooth.js)。我沒有測試它,但有一個[示例](http://osuushi.github.io/plotdemo016.html),它可能值得使用。 – Prusse

0

我正在探索所有的技術,但沒有得到任何適當的解決方案,以平滑畫布上的自由繪畫。然後,我簡單地使用quadraticCurveTo以不同的邏輯,而不使用原始的鼠標點。

我首先計算了控制點(中點),並用控制點替換了舊的鼠標移動點。我做了2次,最後將quadraticCurveTo應用到最終數組,並且我得到了超級平滑的繪圖。

這太棒了。我沒有使用這個沉重的paper.js和其他平滑庫。

這裏是我的代碼:

currentCanvas.beginPath(); 
     currentCanvas.lineCap = 'round'; 
     currentCanvas.strokeStyle = "black"; 
     currentCanvas.lineWidth = "2"; 
     currentCanvas.moveTo(queue[0].x, queue[0].y); 

     //queue is an array of original points which were stored while onmousemove event callback 

     var tempQueue1 = [queue[0]]; 
     for (var i = 1; i < queue.length - 1; i = i+1) { 
      //if((Math.abs(queue[i].x - queue[i-1].x) >3 || Math.abs(queue[i].x - queue[i-1].x)<1) && (Math.abs(queue[i].y - queue[i-1].y) >3 || Math.abs(queue[i].y - queue[i-1].y)<1)){ 
       var c = (queue[i].x + queue[i + 1].x)/2; 
       var d = (queue[i].y + queue[i + 1].y)/2; 
       //tempQueue.push(queue[i]); 
       tempQueue1.push({x:c, y:d}); 
       //currentCanvas.quadraticCurveTo(queue[i].x, queue[i].y, c, d); 
      //} 
     } 

     var tempQueue2 = [tempQueue1[0]]; 
     for (var i = 1; i < tempQueue1.length - 1; i = i+1) { 
      //if((Math.abs(queue[i].x - queue[i-1].x) >3 || Math.abs(queue[i].x - queue[i-1].x)<1) && (Math.abs(queue[i].y - queue[i-1].y) >3 || Math.abs(queue[i].y - queue[i-1].y)<1)){ 
       var c = (tempQueue1[i].x + tempQueue1[i + 1].x)/2; 
       var d = (tempQueue1[i].y + tempQueue1[i + 1].y)/2; 
       //tempQueue.push(queue[i]); 
       tempQueue2.push({x:c, y:d}); 
       //currentCanvas.quadraticCurveTo(queue[i].x, queue[i].y, c, d); 
      //} 
     } 

     var tempQueue = [tempQueue2[0]]; 
     for (var i = 1; i < tempQueue2.length - 1; i = i+1) { 
      //if((Math.abs(queue[i].x - queue[i-1].x) >3 || Math.abs(queue[i].x - queue[i-1].x)<1) && (Math.abs(queue[i].y - queue[i-1].y) >3 || Math.abs(queue[i].y - queue[i-1].y)<1)){ 
       var c = (tempQueue2[i].x + tempQueue2[i + 1].x)/2; 
       var d = (tempQueue2[i].y + tempQueue2[i + 1].y)/2; 
       //tempQueue.push(queue[i]); 
       tempQueue.push({x:c, y:d}); 
       //currentCanvas.quadraticCurveTo(queue[i].x, queue[i].y, c, d); 
      //} 
     } 

     for (var i = 1; i < tempQueue.length - 2; i = i+1) { 
      //if((Math.abs(queue[i].x - queue[i-1].x) >3 || Math.abs(queue[i].x - queue[i-1].x)<1) && (Math.abs(queue[i].y - queue[i-1].y) >3 || Math.abs(queue[i].y - queue[i-1].y)<1)){ 
       var c = (tempQueue[i].x + tempQueue[i + 1].x)/2; 
       var d = (tempQueue[i].y + tempQueue[i + 1].y)/2; 
       currentCanvas.quadraticCurveTo(tempQueue[i].x, tempQueue[i].y, c, d); 
      //} 
     } 

     // For the last 2 points 
     currentCanvas.quadraticCurveTo(
     tempQueue[i].x, 
     tempQueue[i].y, 
     tempQueue[i+1].x, 
     tempQueue[i+1].y 
     ); 
     currentCanvas.stroke(); 
     queue = [];