0

我正在尝试创建一个 html 画布,用户可以在其中定义起点和终点,在起点和终点之间我想画一条波浪线,我通过绘制 bezierCurveTo 来做到这一点。

一个样品:

采样波

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

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。我知道我必须计算控制点,但我不知道我必须使用什么公式。有人可以帮我吗?

4

1 回答 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 为您进行旋转并绘制直线。它使生活变得如此轻松。

于 2013-04-02T19:56:55.937 回答