我正在开发一个简单的白板应用程序,其中的绘图由二次贝塞尔曲线表示(使用 JavaScript 的CanvasPath.quadraticCurveTo函数)。我正在尝试实现功能,以便橡皮擦工具或选择工具能够确定它们是否正在触摸绘图。
为了展示我所说的内容,下图中是一个红色绘图,我需要能够确定黑色矩形和黑点与绘图区域重叠。出于调试目的,我添加了蓝色圆圈(曲线的控制点)和绿线(与贝塞尔曲线相同,但宽度要小得多)。
我已经包含了生成贝塞尔曲线的代码:
context.beginPath();
context.moveTo(localPoints[0].x, localPoints[0].y);
let i;
for (i = 1; i < localPoints.length - 2; i++)
{
let xc = (localPoints[i].x + localPoints[i + 1].x) / 2;
let yc = (localPoints[i].y + localPoints[i + 1].y) / 2;
context.quadraticCurveTo(localPoints[i].x, localPoints[i].y, xc, yc);
}
// curve through the last two points
context.quadraticCurveTo(localPoints[i].x, localPoints[i].y, localPoints[i + 1].x, localPoints[i + 1].y);
context.stroke();
Run Code Online (Sandbox Code Playgroud)
我已经能够找到有关如何确定线段是否与贝塞尔曲线相交的答案,但我无法找到如何确定某些东西是否不与实际曲线相交但足够接近以被视为重叠其“区域”。为此,我认为我需要找到曲线和矩形/点之间的距离,然后确保距离小于用于绘制曲线的宽度,但我不确定如何找到该距离。
一些有趣的文章/帖子:
https://coderedirect.com/questions/385964/nearest-point-on-a-quadratic-bezier-curve
如果它不起作用也许你可以看看这个库:https://pomax.github.io/bezierjs/
正如 Pomax 在评论中所建议的,您正在寻找的东西在图书馆中,并且看起来有一个正确的解释。
如果您想尝试的话,有一个现场演示: https: //pomax.github.io/bezierinfo/#projections
它的源代码在这里: https: //pomax.github.io/bezierinfo/chapters/projections/项目.js
要使用它,请按照 GitHub 中的步骤安装它:https://github.com/Pomax/bezierjs
当然要归功于 Pomax 推荐了他的图书馆