gpt4 book ai didi

javascript - 在 Canvas 中检测鼠标与闭合贝塞尔曲线形状的碰撞

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:14:03 25 4
gpt4 key购买 nike

我的情况:

我正在开发用于缩放用户界面的 HTML5/Canvas/JavaScript 框架,然后将其用于数据可视化 Web 应用程序项目。我的框架需要的功能之一是能够检测用户的鼠标是否在呈现的形状上。对于更复杂的形状,例如多边形和具有贝塞尔曲线的形状,这就成了一个挑战。

我找到了解决这个问题的两种方法:

(1) 一种方法是在 Canvas 上绘制两次。第一次,每个形状都用哈希表中的唯一颜色填充。第二次,形状在第一层上获得了它们的真实颜色和蒙版。要检测鼠标形状碰撞,我必须从第一层抓取鼠标下方像素的颜色,并将我获得的颜色映射到哈希表中的相应形状。

(2) 或者我可以使用光线转换算法 ( http://en.wikipedia.org/wiki/Point_in_polygon#Ray_casting_algorithm )。我实际上已经使用检测射线碰撞和射线贝塞尔碰撞的代码实现了这个算法。

实际问题:

我不喜欢第一种方法,因为所有内容都必须绘制两次,这在计算上并不便宜。但由于计算的舍入误差,第二种方法不能保证准确性。

理想情况下,我想将第二种方法的准确性提高到近乎完美。

我尝试提高准确性的方法是向不同方向转换 4 条光线:顶部、左侧、底部和右侧。如果至少一条水平射线和一条垂直射线表明鼠标在形状内部,那么我断定该点在形状内部。虽然这消除了大多数失火,但当鼠标在形状内部时仍然会发生错误(未启动)。

如果有人可以建议修复光线转换算法,甚至可能是第三种选择,那就太棒了!

提前致谢。

最佳答案

您可以进行光线转换,但您也可以在上下文中使用内置函数:

var flag = ctx.isPointInPath(x, y);

您需要做的只是重建您要测试的每条路径(无需描边或填充它们)并进行此测试。

还有:

var flag = ctx.isPointInStroke(x, y);

如果您还想考虑笔划本身,以防它的宽度 > 1。不过,目前 IE 尚不支持此功能。

例如:

/// build some polygon/shape/...
ctx.beginPath();;
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.lineTo(x3, y3);
ctx.closePath();

/// no need to fill/stroke it, just test the path:
var flag = ctx.isPointInPath(x, y);

您需要为每个独特的形状执行此操作,但性能非常好,除非您有无数的形状,在这种情况下您可以考虑四叉树等。

要检测您单击的是哪个形状,您可以将形状存储为对象而不是使用唯一的颜色(尽管取决于实际情况),因此当您遍历对象数组时,您将知道您当前正在检查哪个对象,以及是否真正命中然后中止迭代。

关于javascript - 在 Canvas 中检测鼠标与闭合贝塞尔曲线形状的碰撞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20275316/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com