【问题标题】:how to determine whether a point lies inside a rectangle? [duplicate]如何判断一个点是否在矩形内? [复制]
【发布时间】:2011-05-18 15:30:48
【问题描述】:

可能重复:
Finding whether a point lies inside a rectangle or not

有一个面试题是“如何判断一个点是否在矩形内”

请注意,矩形也可以旋转。所以在矩形内检查点的简单解决方案在这里不成立......

请分享您对这个问题的看法..

我在互联网上找到了一个链接,并试图理解它,但失败了......请如果这里有任何人可以用一点计算机图形逻辑给出完整的解决方案,因为我已经忘记了所有的基础知识...... . How to determine if a point is inside rectangle.

【问题讨论】:

  • 这类面试问题与答案无关,否则就不会那么模糊。他们只是好奇你是如何思考的,以及你如何很好地传达这些想法......
  • 你得到了什么?四个(或三个)点的坐标?一点和两条边?两个相反的点和一条线?您的问题没有说明任何内容。

标签: c++ c algorithm computational-geometry


【解决方案1】:

选择一个绝对在矩形之外的点。然后创建从该点到相关点的段。求解该线段与构成矩形的线段之间的交点的线性方程。如果您恰好得到一个交点,则该点位于矩形内。否则(0 或 2 个交叉点),它在外面。

这几乎可以扩展到任何多边形——奇数个交叉点表示该点在多边形内部,偶数个表示它在外部。

编辑:这可能不是很明显,所以我要强调的是,我们在矩形(多边形)之外选择的点是完全任意的。只要我们确定它在多边形之外,我们就可以选择我们想要的任何点。为了简化计算,我们通常会选择 (Px, infinity)(其中 Px 是我们所在的点 P 的 x 坐标测试)——也就是说,我们创建的本质上是一条垂直射线。这稍微简化了测试,因为我们只需针对一个端点进行测试即可找到交叉点。它还简化了线性方程组的求解,以至于几乎无法识别为求解线性方程组。我们真的只需要计算 Px 处的直线的 Y 坐标,看看它是否大于 Py。因此,求解线性方程分解为:

  1. 检查 X 值是否在段的 X 值范围内
  2. 如果是,将 X 值代入直线方程
  3. 测试得到的Y值是否大于Py

如果这些通过,我们就有了一个交叉点。另请注意,测试可以并行执行(如果我们在 GPU 等并行硬件上执行此操作会很方便)。

【讨论】:

  • 这可能是最好的答案。 (+1)
  • 在你说之前先读我的。 :)
  • 当路段通过一个角落时,事情变得复杂了。该段可以进入内部或留在外部(仅在一点“触摸”矩形),您无法轻松地在两者之间做出决定。
  • @R。 IMO,您的解决方案在数学上很棒,但我无法想象在大多数实际代码中使用它。首先,它需要一个对于所述任务来说非常不寻常的表示。其次,我怀疑超过 20 个维护程序员根本不会理解它。在只有真正的专家才能接触到的几何引擎的深处,它可能没问题。在大多数典型代码中,我通常更喜欢更直观的东西。
  • 好吧,我认为您可以将其简化为几行代码,甚至从“更典型”的表示形式转换,然后只需一个有意义的函数名称和注释就足以让任何人保持如果他们不懂几何,就需要查看内部结构......
【解决方案2】:

适用于 N 维凸多面体的简单解决方案,其中二维矩形是​​一种特殊情况:

  1. 将多面体表示为半空间的交集,每个半空间由单位法线向量和曲面超平面沿法线到原点的距离定义。
  2. 对于这些半空间中的每一个,取相关点与定义法线向量的点积。当且仅当点积小于[或等于]定义距离时,该点才在半空间中。
  3. 该点在多面体内部当且仅当它在每个半空间中。

对于定义为逆时针序列边缘的矩形,步骤 1 相当于将每个边缘顺时针旋转 90 度以获得法线,然后将法线与包含边缘的线相交以找到到来源。

假设步骤 1 已完成,测试一个点最多需要 8 次乘法、4 次加法和 4 次比较。

如果你愿意,你可以稍微优化一下这个过程,因为你有矩形(因此相对的边有相反的法线)。现在您只查看 2 个法线而不是 4 个法线,以及一系列点积值,这些值指示位于相对两侧之间的点。所以现在你只需要 4 次乘法、2 次加法和 4 次比较。

如果您进行的第一个测试显示该点位于矩形之外,您也可以很幸运,在这种情况下,它只是 2 次乘法、1 次加法和 1-2 次比较。

【讨论】:

  • 非常优雅的解决方案,尽管我确实必须弄清楚您所说的“半空格”是什么意思。
  • 半空格只是所有x 的集合,因此x·v < c 用于某些固定的vc(或,如果您愿意)。
【解决方案3】:

这远非最佳解决方案...但是如果您有连续顺序的点,请将它们称为 abcd,并带有 x 和 y 字段,您可以使用您的点 p 和每个连续对之间的向量的叉积。

如果结果的符号总是相同(即全部为正或全部为负),那么您在矩形内;否则,你就在外面。

【讨论】:

  • 我相信这只适用于凸四边形,但假设它是一个矩形,那就没问题了。不过,这不是批评,只是说。
  • 你能举个例子来支持你的答案吗...??
  • 它适用于任何凸多边形。
  • 我实际上在想我可能会删除这个答案——我在问题 cmets 中放了一个我更喜欢的链接。
  • 有趣的是,同样的问题是如何在一年中的同一时间出现的——您链接到的 AndreyT 的答案距离正好一岁只有大约一周的时间! :-)
【解决方案4】:

定义一个以两个矩形边为单位向量的新坐标系,并将点的坐标变换到新的坐标系中。如果两个坐标都在 0 和 1 之间,则它在里面。

在方程中(假设 A,B,C,D 是矩形的角,P 是点,_x 和 _y 是 x 和 y 分量):

P_x = A_x + x * (B_x - A_x) + y * (D_x - A_x)
P_y = A_y + x * (B_y - A_y) + y * (D_y - A_y)

求解 x 和 y 并检查它们是否在 0 和 1 之间

写成线性方程组(A,B,C,D,P 是长度为 2 的向量):

[    |    ]   [x]   [   ]
[B-A | D-A] * [ ] = [P-A]
[    |    ]   [y]   [   ]

求解很简单,因为它只有两个维度,而且您可以确定自己不是单数。

【讨论】:

    【解决方案5】:

    您可以旋转和移动参考系,使其与矩形的位置和旋转相匹配。现在只是坐标之间的简单比较。这更像是一种数学方法,所以不是最快的(相信@Platinum Azure 的方法)

    【讨论】:

      【解决方案6】:

      由于矩形可以旋转,您可能需要考虑一种算法来确定a point is interior to a convex polygon 是否存在。

      您还可以计算矩形的旋转角度,然后变换矩形和点以轴向对齐矩形。然后检查变换后的点是否在轴向对齐的矩形内。

      【讨论】:

      • “一般多边形”是困难且不必要的。 “一般凸多边形”是您要考虑的。
      • @R.:同意。答案已更新。
      【解决方案7】:

      确定一个点是否位于矩形等有界区域内是经典裁剪算法的一部分。请参阅ClippingLine Clipping 上的维基百科文章以了解更多信息。

      【讨论】:

        【解决方案8】:

        遵循@Jerry Coffin 的精神:创建从矩形角到相关点的线段。求解线性方程。坡度为tan(a)。总结所有 seq 反正切 diff,如果它是 2*PI 并且每个 diff

        编辑可能只检查每个顺序差异就足够了

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-02-01
          • 1970-01-01
          • 2023-03-18
          • 2023-03-31
          • 1970-01-01
          • 2022-10-22
          • 1970-01-01
          相关资源
          最近更新 更多