javascript画布两个path2D之间的交集



我正在寻找一种方法来检查两个path2D是否相交,但无法找到方法…

为例:

// My circle
let circlePath = new Path2D();
circlePath.ellipse(x, y, radiusX, radiusY, 0, 0, Math.PI*2, false);
// My rectangle
let rectPath = new Path2D();
rectPath.rect(x, y, width, height);
// Intersect boolean
let intersect = circlePath.intersect(rectPath); // Does not exists

有这样的函数吗?

我找到了isPointInPath(path2D, x, y)(我用我的路径来检查与鼠标相交),但不能在两条路径之间使用它。

或者可能是一种方法来获得Path2D中所有点的数组,以使用isPointInPath与所有点?

编辑:

仅供参考,我希望这能够用于游戏开发,我希望能够检查实体之间的碰撞(实体是由一些数据和Path2D定义的)。我的实体可以是正方形、圆形或更复杂的形状。

目前API中没有此功能。

Path2D界面仍然只是一个不透明的对象,我们甚至不能从中提取路径数据。实际上,我确实开始在未来的提议中工作,以公开此路径数据并向Path2D对象添加更多方法,如getPointAtLength(),或导出到SVG路径命令,这将有助于做你想做的事情,但我不会屏住呼吸,直到它成为API的一部分,我必须承认我甚至没有考虑包括这样的路径相交方法…

然而,作为这项工作的一部分,我确实构建了该API的原型,目前只暴露了一些预期的方法:https://github.com/Kaiido/path2D-inspection/
在这些方法中,有一个toSVGString()可以与这个项目一起使用(我没有广泛测试)。

所以我们可以通过合并两个库来构建Path2D#intersects()。但是请注意,至少我的(path2d-inspection)还没有经过广泛的测试,我不建议在生产中使用它。
无论如何,这里有一个非常快速的hack作为概念验证:

const circlePath = new Path2D();
circlePath.ellipse(rand(100, 20), rand(100, 20), rand(80, 10), rand(80, 10), rand(Math.PI*2), 0, Math.PI*2, false);
// My rectangle
const rectPath = new Path2D();
rectPath.rect(rand(150), rand(100), rand(200), rand(200));
// Intersect boolean
const intersect = rectPath.intersects(circlePath);
console.log("intersect:", intersect);
// List of intersection points
const intersections = rectPath.getIntersections(circlePath);
console.log(intersections);
// Render on a canvas to verify
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
ctx.strokeStyle = "green";
ctx.stroke(circlePath);
ctx.strokeStyle = "red";
ctx.stroke(rectPath);
function rand(max=1, min=0) {
return Math.random() * (max - min) + min;
}
.as-console-wrapper { max-height: 50px !important }
<script src="https://cdn.jsdelivr.net/gh/Kaiido/path2D-inspection@master/build/path2D-inspection.min.js"></script>
<script>
// a really quick hack to grasp 'intersect' from their esm
globalThis.module = {};
</script>
<script src="https://cdn.jsdelivr.net/gh/bpmn-io/path-intersection@master/intersect.js"></script>
<script>
// part 2 of the hack to grasp 'intersect', let's make it a Path2D method :P
{
const intersect = module.exports;
delete globalThis.module;
Path2D.prototype.getIntersections = function(path2) {
return intersect(this.toSVGString(), path2.toSVGString());
};
Path2D.prototype.intersects = function(path2) {
return this.getIntersections(path2).length > 0;
};
}
</script>
<canvas></canvas>

最新更新