这是我的 2 美分:
你的建议很像使用四叉树命中测试:
http://gamedev.tutsplus.com/tutorials/implementation/quick-tip-use-quadtrees-to-detect-likely-collisions-in-2d-space/
您的网格就像四叉树,因为您正在寻求生成目标区域中存在的线列表并消除目标区域中不存在的线。
因此,您的网格提供了一种最初关注命中测试的方法。
初始焦点后,您仍需要检查焦点列表中的每一行,以查看点击是否命中任何行。
我不能说这个初始焦点是否比命中测试线的替代方法更快。
我怀疑如果画布很大并且有很多线条,那么您的网格焦点可能会有所帮助。
我想您可以尝试使用您的想法 [相对于或结合] 下面更传统的替代方案。
备择方案:
正如@Ken-AbdiasSoftware 在他的链接中所说,您可以使用 context.isPointInStroke 和 context.isPointInPath 进行命中测试。这两个现有的命中测试快速有效。
这些命中测试方法在大多数支持画布的现代浏览器中都可用,并且 [可能] 已被浏览器优化。
IE 支持 context.isPointInPath 但还不支持 context.isPointInStroke。
对于 IE,您可以“作弊”并使用 context.isPointInPath,方法是将每一行转换为非常窄的封闭路径。
或者对于 IE,行命中测试的快速但内存密集型替代方案可能是:
- 清除画布,
- 在画布上画一条线,
- 使用 context.getImageData 获取 RGBA 像素数据的数组
- 保存一个仅包含像素 alpha 值的新子数组(仅保存“RGBA”中的“A”)。
- 重要性:新的 alpha 数组在此特定行存在的地方将具有值>0。
- 对所有其他行在 #1 处重复。
然后,您可以通过在任何指定的 x/y 坐标处检查其 alpha 数组来“命中测试”每一行。
如果指定坐标处的 alpha 数组 >0,则该线存在于该像素处。
这种方法有一个变体,它使用更少的内存但使用更多的处理。
对于任何线条,画布上的空白空间都比“行”的空间多。
您可能有一个仅包含大于 0 的像素位置的数组。
然后通过扫描数组来进行命中测试以确定指定的 x/y 坐标是否在数组中。