用画布绘制流畅的线条

时间:2011-10-25 15:31:42

标签: javascript canvas drawing bezier smoothing

到目前为止,平滑线上的线程都没有正确。

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

Smooth user drawn lines in canvas

两者都会产生锯齿状的线条。通过平滑我的意思是使用x,y点作为控制点以使线条平滑。该线不需要经过这些点。它只需要给出n个点的平滑线。

基本上我正在录制每个线段,然后当用户将鼠标移动时,它会使线条平滑。

我使用bezierCurveTo尝试了自己的方法但是只能平滑每个其他点,然后连接点仍然很苛刻。互联网似乎认为我正在寻找的是B-Spline曲线。我尝试将线性代数矩阵应用于问题,但我在那个哈哈失败了。

这是我能得到的最佳曲线,(图片)。红线是“平滑”线,你可以看到它平滑每一点,但不是连续的。这是使用

中的代码

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

我的代码做同样的事情

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

感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

您需要在线下方的点中保持相同的切线。检查http://jsfiddle.net/FHKuf/4/

编辑:

抱歉,今天就注意到了你的评论。恰巧正在测试相关的东西并记住你的问题。碰巧在过去我写了一些代码来插入一些行。它被称为Catmull-Rom(只是我所说的参考)它通过中间控制点。我确实将代码更改为我的测试,并认为您可能对它有一些用处。见http://jsfiddle.net/FHKuf/6/

答案 1 :(得分: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 = [];