寻找二次贝塞尔曲线与点或矩形之间的最短距离

Finding the shortest distance between a quadratic Bezier curve and point or rectangle

我正在开发一个简单的白板应用程序,其中的绘图由二次贝塞尔曲线表示(使用 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();

我已经能够找到关于如何确定线段是否与贝塞尔曲线相交的答案,但我无法找到如何确定某物是否不与实际曲线相交但足够接近以至于可以被认为与其“区域”重叠。为此,我认为我只需要找到曲线与 rectangle/point 之间的距离,然后确保距离小于用于绘制曲线的宽度,但我不确定如何找到它距离.

有些有趣articles/posts:

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/project.js

要使用它,请按照 GitHub 中的步骤进行安装:https://github.com/Pomax/bezierjs

当然要感谢 Pomax 推荐他的图书馆