当使用canvas绘图时,如何在两个点之间插值?

4
我有一个涂鸦应用程序,可以使用触摸事件进行操作。
JavaScript代码如下...
var RADIUS = 10;
var ctx = document.querySelector("canvas").getContext("2d");

var getRandomColorFragment = function () {
    return Math.floor(Math.random() * 255);
};

document.body.addEventListener("touchstart", function (event) {
    ctx.fillStyle = "rgb(" + [getRandomColorFragment(), getRandomColorFragment(), getRandomColorFragment()].join() + ")";
});

document.body.addEventListener("touchmove", function (event) {
    // Prevent default behavior of scrolling elements.
    event.preventDefault();

    // Get a reference to the first touch placed.
    var touch = event.touches[0];

    // Draw a circle at the location of the finger.
    ctx.beginPath();
    ctx.arc(touch.pageX - RADIUS, touch.pageY - RADIUS, RADIUS, 0, Math.PI * 2);
    ctx.closePath();
    ctx.fill();
});

jsFiddle.

如果您想在不支持触摸事件的平台上测试,请使用Chrome并打开Web Inspector的设置,然后选择模拟触摸事件

当手指/指针移动得非常快时,它无法像预期那样连续地绘制画布(请参见上面的截图)。似乎我只能以touchmove事件被触发的速度获取触摸坐标。

我认为可以使用距离公式(c2 = a2 + b2)确定弧之间是否有足够大的间隔,以及确定这个间隔是否大于RADIUS常量。这部分效果很好。下一步我需要解决的问题是如何在两点之间进行插值:先前注册的触摸坐标和新注册坐标之间的两点。

因此,基本上,我想知道如何在我有的两个点之间进行插值以确定如何填补间隙。


那么在这两个点之间迭代(使用Bresenham线算法),并在您访问的每个单独点上绘制圆形呢? - Ondrej Svejdar
Bresenham算法无法绘制带圆角的“粗”线条。但是已经实现了“lineTo”方法。 - Ivan Kuckir
1个回答

11

你想要从上一次鼠标位置画一条线到新的鼠标位置,但是你却在新位置画了一个圆。为什么?

为什么不这样做呢?

onTouchStart: ctx.moveTo(x,y);

onTouchMove: ctx.lineTo(x,y);

所有插值、反锯齿等都已包含在“lineTo”函数中。使用ctx.lineCap = "round";可获得圆角。

如果您仍希望进行数值插值,以下是该函数:

function interpolate(a, b, frac) // points A and B, frac between 0 and 1
{
    var nx = a.x+(b.x-a.x)*frac;
    var ny = a.y+(b.y-a.y)*frac;
    return {x:nx,  y:ny};
}

interpolate({x:2, y:2}, {x:4,y:4}, 0.5); // returns {x:3, y:3}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接