检查点是否尽可能高效地位于轴对齐的矩形内,包括边缘?

时间:2017-02-06 06:13:55

标签: algorithm math geometry

我正在开发一个交互式Web应用程序,我目前正致力于实现一个多选功能,类似于Windows允许您通过拖动矩形选择多个桌面图标的方式。

由于我需要使用的库的限制,实现它已经变得非常耗费资源:

  1. 初次点击时,存储鼠标光标的位置。
  2. 在鼠标光标移动的每个像素上,执行以下操作:

    1. 销毁上一个选择矩形(如果存在),因此它不再出现在屏幕上。
    2. 使用当前光标位置和当前光标位置计算新选择视角的宽度和高度。

    3. 使用原始光标位置,宽度和高度创建一个新的选择矩形

    4. 在屏幕上显示此矩形
  3. 正如您所看到的,每次光标移动单个像素时都会发生很多事情。我尽可能多地研究了这个问题,我无法让它变得更有效率或更快。

    我的下一步是在选择矩形移过它们时实际选择屏幕上的对象。我需要自己实现这个算法,所以我可以自由地使它尽可能高效/快速。我需要做的是遍历屏幕上的对象并检查每个对象以查看它是否位于矩形中。所以这里的循环将消耗更多的资源。所以,我需要尽可能高效地完成检查。

    可以选择的每个对象都可以用单个点P(x,y)表示。

    如何检查P(x,y)是否在我以最快/最有效的方式创建的矩形内?

    以下是相关信息:

    • 可以是任意次数可在屏幕上选择的任意数量的对象
    • 选择矩形将始终为轴对齐
    • 我对矩形的信息是它们的原始点,它们的高度和宽度。

    如何尽快实现我需要做的事情?

2 个答案:

答案 0 :(得分:0)

检查点P是否位于矩形R内是简单快速的 (在左上角有原点的坐标系中)

(P.X >= R.Left) and (P.X <= R.Right) and (P.Y >= R.Top) and (P.Y <= R.Bottom) 

(预先计算矩形的右边和底边坐标)

如果对象满足某些条件,也许你可以加速整体算法,这样就不会在每一步检查所有对象。

示例:按X坐标对对象列表进行排序,并仅检查位于Left..Right范围

中的对象

更高级的方法:在kd-tree等空间分区数据结构中组织对象,并快速执行范围搜索

答案 1 :(得分:0)

您可以使用以下条件遍历屏幕上的每个对象并检查它是否位于笛卡尔坐标系中的矩形中:

p.x >= rect.left && p.x <= rect.right && p.y <= rect.top && p.y >= rect.bottom

如果屏幕上的点数不超过1000点,只需使用天真的O(n)方法迭代每个点。如果您完全确定需要进一步优化,请继续阅读。

根据更新点的频率和每帧更新的点数,您可能希望使用可能涉及Range Trees等数据结构的其他方法,或者适应原始O(n)方法

  • 如果这些点不会移动很多并且稀疏(即彼此远离),则可以使用Range Tree或类似的O(log n)检查。请记住,更新这样的空间分区结构是资源密集型的,如果你有很多要点会移动很多,你可能想看看别的东西。

  • 如果少数点将要在很远的距离上移动,您可能需要查看将屏幕划分为&#34; buckets&#34;的网格,并且只检查矩形包含的那些桶。每当一个点从一个桶移动到另一个桶时,网格将不得不更新受影响的桶。

    • 如果内存是约束,如果网格方法效率不高,您可能希望查看使用受树深度而不是桶大小限制的修改后的Quad Tree

如果你有很多分数在每一帧都移动很多,我认为你可能会更好地使用网格方法或者只是采用天真的O(n)方法。尝试并选择最适合您的问题的方法。