算法 - O(1) 检查鼠标是否悬停在圆圈数组之一上

algorithm - O(1) to check if mouse hovering one of array of circles

通常检查 mouse move 事件 xy 是否拦截多边形数组中的任何多边形是:

on mousemove (e)->
  for c in circles
     if intercept(e.x, e.y, c)
        ...

只是想知道我是否可以在没有 for 循环的情况下检查它,例如:

on mousemove (e)->
  i = calidx(e.x, e.y)
  if intercept(e.x, e.y, circles[i])

似乎每个 mousemove 遍历所有数组项的事件循环都不是高效的

是否可以使用 O(1) 的复杂度来找出哪个数组项正在悬停?

使用查找 table 使其摊销 O(1)(但 setup/update 很痛苦)

使用 分摊 O(1) 的一种方法是使用 table 查找。这意味着您需要存储每个像素坐标及其所属的圆 ID,如下所示:

pixel(0,0) --> no circle

pixel(0,1) --> circle#1

pixel(0,2) --> circle#1,circle#2

...

因此您可以快速查找具有特定像素坐标的 table 并检索它所属的圆圈。可以使用分摊的 O(1) 完成此查找。

但是,设置 table 或更新它

是一件很痛苦的事

设置查找的算法 table 很痛苦,非常复杂。您需要填充您拥有的每个圆圈的所有像素坐标,并制作完整的 table。这非常复杂,更新现有圈子的新位置更糟。更新查找需要一些计算 table.

这种方法在以下情况下是负担得起的:

  • 你的圈子是静态的。设置圆圈后,它们将不会移动或调整大小。
  • 你有一个小canvas。

相比之下,在以下情况下这是邪恶的,更糟糕​​的是:

  • 你的圈子是动态的。它们一直在移动、调整大小、添加或删除。这使更新阶段付出了巨大的开销。
  • 你有一个大canvas。