2011-10-25 109 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 = [];