Algorithm 找出线段是否完全位于多边形内部

Algorithm 找出线段是否完全位于多边形内部,algorithm,geometry,Algorithm,Geometry,如何确定从p边界上的点a开始到p边界上的点B结束的线段是否完全包含在p内 编辑:在这种情况下,不必检查线段与多边形边界上其他线段的交点,稍后将执行此操作 这可以在恒定时间内完成吗?根据编辑的描述,假设多边形很简单,它以逆时针排序的顺序表示为线段列表,查询线段的内部不与多边形的边界相交,并且对于查询线段的任一端点,我们知道哪些多边形段包含该端点 如果端点是多边形顶点,则有两种可能的情况。通过使用2D行列式测试比较相对于顶点的角度,可以在恒定时间内区分这些点 Case 1: segment not

如何确定从p边界上的点a开始到p边界上的点B结束的线段是否完全包含在p内

编辑:在这种情况下,不必检查线段与多边形边界上其他线段的交点,稍后将执行此操作


这可以在恒定时间内完成吗?

根据编辑的描述,假设多边形很简单,它以逆时针排序的顺序表示为线段列表,查询线段的内部不与多边形的边界相交,并且对于查询线段的任一端点,我们知道哪些多边形段包含该端点

如果端点是多边形顶点,则有两种可能的情况。通过使用2D行列式测试比较相对于顶点的角度,可以在恒定时间内区分这些点

Case 1: segment not in polygon

        \ query segment
         \
*<--------*<--------*
  polygon
  interior


Case 2: segment in polygon

*<--------*<--------*
  polygon  \
  interior  \ query segment
旋转(并缩放,这并不重要)所有内容,以便查询段位于x轴上。这是通过乘以矩阵来实现的

[ a b]
[-b a]
获取新的图表

        * (ac+bd,ad-bc) = (p,q)
       /
      /
    |_     query
    *-----------* (a^2+b^2,0)
   /
  /
|_
* (ae+bf,af-be) = (r,s).
根据我们的简并假设,
(p,q)!=(0,0)
。现在,
(p,q)
位于上半平面,如果
q>0 | |(q==0&&p>0)
。否则,它在下半平面。对于
(r,s)
,情况类似

如果
(p,q)
位于上半平面,而
(r,s)
位于下半平面,则查询段位于内部。反之亦然,那么它就在外面。否则,这些点位于同一个半平面中。决定因素测试是
ps qr>0
(内部)还是
ps qr<0
(外部)。它不能相等,因为多边形很简单


也许有比我更博学的人可以把这个测试的程度从四分之一降下来。

如果我正确理解了你的问题,你是在试图区分以下两种情况:

  • AB完全在多边形内
  • 除端点外,AB完全位于多边形之外
我们已经排除了AB部分位于多边形内部的情况,因为您已经测试了AB是否与每一侧相交


在我看来,你的问题相当于问AB的中点是否包含在多边形中。维基百科有一篇很好的文章描述了如何确定这一点:。如果你想让事情在数值上保持稳定,我建议使用缠绕数方法。

我编辑了描述,但有一些限制。请你详细说明你的意思:用2D行列式测试比较相对于顶点的角度?应该比较哪些角度?@Geminus补充了详细信息。非常感谢。我不确定我是否完全理解:我必须总是这样旋转,(p,q)到(0,0)和(0,0)到(r,s)的方向是“向下”的?(0,0)是否也描述了查询段的开始或结束?@Geminus简单地说,一个简单的多边形具有这样的特性:当你逆时针沿着边界走的时候,左边的邻域总是在里面,右边的邻域总是在外面。由于查询段不穿过多边形,其内部要么完全在内部,要么完全在外部,因此我们可以从任意靠近端点的点确定整个段的状态。然后,只需观察顶点周围足够小的圆盘。
        * (ac+bd,ad-bc) = (p,q)
       /
      /
    |_     query
    *-----------* (a^2+b^2,0)
   /
  /
|_
* (ae+bf,af-be) = (r,s).