【问题标题】:Determine if Line Segment Between Polygon Vertices is "Inside" Polygon确定多边形顶点之间的线段是否为“内部”多边形
【发布时间】:2021-05-28 03:23:21
【问题描述】:

我正在尝试找到一种有效的算法,该算法可以检查简单(编辑:简单 凹面)多边形中两个顶点之间的线是否包含位于多边形域之外的点。我能找到的最接近的问题是这个:https://stackoverflow.com/a/36378838/12135804

但我不确定答案是否完全正确。可能是这样,在这种情况下,如果有人能澄清一下,那就太好了。

基本思想如下图所示:

我希望红线失败而绿线成功。我知道不能天真地测试中点,因为这在每种情况下都不起作用,但是在多边形域之外的线上找到任何点都应该取消它的资格。

感谢所有帮助!

编辑:忘记包含数学堆栈交换的交叉链接: https://math.stackexchange.com/q/4040059/892519

【问题讨论】:

  • 你的意思是“凸包”吗?搜索那个,这是一个已解决的问题。 ;)
  • 不,编辑得更清楚。这适用于凹多边形。上述算法不会真正应用于凸多边形,因为两个顶点之间的任何线都会自动位于多边形内。话虽如此,它在技术上仍然适用于凸多边形,因为我不介意作为多边形一部分的线。
  • 在非常接近线端点的点上进行 hit test(稍微向内移动到线中心),所以如果线是 AB,那么测试点 C = A + 0.000001*(B-A) ...
  • 我认为这可行,因为这两个点都可以进行多边形点测试,如果一个失败则宾果游戏。

标签: algorithm geometry polygon computational-geometry line-segment


【解决方案1】:

假设最上面的点是A,其他点的名称是BC ...逆时针方向,所以我们知道我们在说什么。

如果您选择红色部分B-D,则中间的一点在左侧。如果您选择绿色部分D-F,则中间的一点在右侧。现在,更有趣的部分是B-E,其中C 位于左侧,D 位于右侧。

为了确定左右,使用向量积。长度取决于sin 函数,所以如果你得到一个小于零的值,它是一侧,大于零是另一侧。

【讨论】:

  • 我没有提到红色和绿色线段的顺序不能保证与其余点一致。我认为如果没有这个假设,叉积不再是一个好的测试(虽然我可能错了)。此外,我不确定中点在一般情况下是否成立,因为它会因锯齿状但几何上简单的多边形而失败。在这种情况下,中点可能在内部。我应该选择一张更好的图片来说明这一点 - 我很抱歉!
【解决方案2】:

在谷歌搜索很多之后,我终于找到了大约 12 年前的一个 stackoverflow 问题的答案:https://stackoverflow.com/a/693877/12135804

假设多边形中的边遵循一定的顺序,可以使用线的起点 (p) 创建简单的 ccw 测试,从该起点开始的多边形中的下一个 ccw 点作为拐点 (q),以及线 (r) 的端点。对于红线BD,测试将检查 B、C、D 是否为 ccw(不是)。对于绿线DF,测试 D、E、F 是否为 ccw(它是!)。即使这些点是不连续的,这也会起作用。但是,当红绿线的顺序颠倒时,这将失败。例如,如果红线变为DB,则测试将检查 D、E、B,这将通过 ccw 测试。

我认为更稳健的解决方案是在凹多边形中搜索两条边,它们共享要测试的线的端点。对于这两对,计算两条边与 x 轴之间的角度。还要计算直线与 x 轴的角度。如果线在多边形内,则线的角度应介于两个端点的多边形边角的最大值和最小值之间。

我认为,是否测试钝角或锐角范围取决于一些因素。红线在B w.r.t 处的角度。到 x 轴将在 ABBC 之间的钝角边界内,在点 C 也是如此。从视觉上看,很明显锐界是两个点的最大/最小测试需要使用的。如果可以从逻辑上选择计算边界的基线,则可以完成。

当然,如果线在两个端点之间的途中越过多边形外部,这将不起作用,但这确实可以处理正常线-多边形相交测试的退化情况。假设它适用于所有退化的情况,也就是说。

我不会将此标记为答案,因为我无法证明它。

编辑:好吧,我又回来思考这个问题,并决定搜索类似于我上面提出的角度边界的问题,并找到了这个:https://stackoverflow.com/a/17497339/12135804

这个答案满足不知道线的方向!但是,它假定应该测试AB 之间的最小界限。这不适用于凹顶点,当 AxB A 和 B 共享的顶点的线如果指向多边形外部,则返回 true,反之则返回 false如果它在里面。不过,我认为根据AxB 的符号翻转结果应该足以说明这一点。 (在此相关答案中验证的预感:https://stackoverflow.com/a/43384516/12135804

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-22
    • 1970-01-01
    • 2020-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-26
    相关资源
    最近更新 更多