仅使用start和endpoint创建beziers曲线

时间:2013-04-01 19:56:46

标签: javascript canvas bezier

我正在尝试创建一个html画布,用户可以在开始和终点之间定义一个起点和终点,我想画一条挥动线,我是通过绘制bezierCurveTo来做到的。

样本:

sample wave

我用来绘制它的代码如下:

var wave = new Kinetic.Shape({
        drawFunc: function (canvas) {
            var ctx = canvas.getContext();
            ctx.beginPath();
            ctx.moveTo(50, 50);
            var waveCount = 0;
            var controlPoint1X = 55;
            var controlPoint2X = 60;
            var endPointX = 65;
            while(waveCount < 10) {
                ctx.bezierCurveTo(controlPoint1X, 35, controlPoint2X, 65, endPointX, 50);
                controlPoint1X += 20;
                controlPoint2X += 20;
                endPointX += 20;
                waveCount++;
            }
            ctx.stroke(_this);
        },
        stroke: '#000000',
        strokeWidth: 2
    });

只要x或y坐标发生变化,我就可以完成这项工作。现在我希望能够创建如上所示的波浪线,但具有不同的x,y坐标。例如,起始点x:50 y:50和端点x:100 y:100。我知道我必须计算控制点,但我无法找出我必须使用的公式。有人可以帮助我吗?

1 个答案:

答案 0 :(得分:1)

让我们在一条直线上模拟一个圆和正弦波。对于半圆,每个“句点”由两个段组成,其中段1为:

cDist = 4/3 * amplitude

(我们从http://pomax.github.com/bezierinfo/#circles_cubic知道这一点)

S = (x1, 0),
C1 = (x1, cDist)
C2 = (x2, cDist)
E = (x2, 0)

和第二部分是:

S = (x2, 0),
C1 = (x2, -cDist)
C2 = (x3, -cDist)
E = (x3, 0)

对于正弦波,控制点几乎相同; y坐标保持相同的高度,但是我们需要移动x坐标,使得形状在起点和终点处具有校正的角度(对于圆形,它们是垂直的,对于正弦波,它们是对角线):

S = (x1, 0),
C1 = (x1 + cDist/2, cDist)
C2 = (x2 - cDist/2, cDist)
E = (x2, 0)

和第二部分是:

S = (x2, 0),
C1 = (x2+cDist, -cDist)
C2 = (x3-cDist, -cDist)
E = (x3, 0)

我在http://jsfiddle.net/qcUyC/6

提出了这个演示

如果您希望这些线条处于固定角度,我的建议是:旋转您的上下文。实际上不要改变你的坐标。只需使用context.rotate(...)就可以了。见http://jsfiddle.net/qcUyC/7

但是,如果绝对需要的坐标不仅仅是在正确的位置绘制,而是具有代表真实角度线的坐标,那么从你的角度开始:

angle = some value you picked, in radians (somewhere between 0 and 2*pi)

以这个角度,我们可以提出我们的观点:

dx = some fixed value we pick
dy = some fixed value we pick

ox = the x-offset w.r.t. 0 for the first coordinate in our line
oy = the y-offset w.r.t. 0 for the first coordinate in our line

x1 = ox
y1 = oy

x2 = (dx * cos(angle) - dy * sin(angle)) + ox
y2 = (dx * sin(angle) + dy * cos(angle)) + oy

x3 = (2*dx * cos(angle) - 2*dy * sin(angle)) + ox
y3 = (2*dx * sin(angle) + 2*dy * cos(angle)) + oy

...

xn = ((n-1)*dx * cos(angle) - (n-1)*dy * sin(angle)) + ox
yn = ((n-1)*dx * sin(angle) + (n-1)*dy * cos(angle)) + oy
然后,您必须将控制点视为相对于线段起点的矢量,因此C1'= C1-S,C2'= C2-S,然后旋转具有相同变换的控制点。然后,将这些向量添加回起点,现在可以正确旋转控制点。

那就是说,不要这样做。让canvas2d API为你做旋转,只绘制直线。它让生活变得如此简单。