关于算法:计算圆是否适合多边形(三角形/五边形)内部给定的坐标允许触摸多边形?

Calculate if circle fits inside of polygon (triangle/pentagon) given coordinates where touching the polygon is allowed?

给定一个圆心(xc,yc)和半径r以及在数组内部具有顶点的多边形,以便顶点[]=(xv1,yv1),…,(xvn,yvn)其中n是顶点数。

我想知道圆是否在多边形的内部。我假设(并且可以安全地假设)多边形没有孔。

我检查的唯一多边形是三角形和五边形。

到目前为止,我所做的就是计算圆心是否在多边形内。此函数称为isInside()

如何检查圆是否完全在我要检查的多边形内?接触是可以的。

更具体地说,我在计算圆和多边形之间的关系时遇到了困难,这对于解决这个问题至关重要。我知道如何找到圆心是否在多边形内,但不知道完整的圆是否包含在多边形内。

有什么帮助的:)


下面假设您已经知道圆心在多边形内。有一些事情你想检查作为你的定义,接触顶点是可以添加一些角箱。这个解决方案也适用于凹多边形。

早期检查

为了使圆完全在多边形内,我们需要所有边都在圆外。尤其是这样可以确保多边形不完全位于圆内。

给定半径为r且以c为中心的圆和多边形的边e0、e1、…、en

d(c, ei) >= r

其中d是欧几里得距离。

如果上面没有任何边,那么多边形和圆之间有一个交点,或者多边形完全在圆内。

圆与多边形相交吗

最后一次检查是圆在内部的必要条件,尽管这是不够的,因为可能的是所有边缘都在圆的外部,但圆仍然漏出垂直线。

让我们先记住一些我们需要的公式。

以(x0,y0)为中心的半径r圆的方程:

(x - x0)2 + (y - y0)2 = r2

因此,与线y=ax+b的交点可通过求解得出:

(x - x0)2 + (ax + b - y0)2 = r2

这只是一个二次方程,可以改写为:

(a2 + 1)x2 + (2ab - 2ay0 - 2x0)x + (x0 + (b - y0)2 - r2) = 0

你可以用每个顶点的二次公式来解决这个问题。然后你有三种可能。

1)没有解决方案

这表示不存在与此顶点的交集。使用高级语言,您可以捕获一些MathError异常来检测这一点。否则,您可以用数学方法检查判别式的符号,因为如果是负数,则会发生这种情况。

(2ab - 2ay0 - 2x0)2 - 4 (a2 + 1) (x0 + (b - y0)2 - r2) < 0

2)有独特的解决方案

如果方程只有一个解,即两个解都是相同的,那么圆可能会接触,但不会从边缘漏出。你说在你的例子中这仍然被认为是在多边形内部。

在数学上,当判别式为零时就会发生这种情况。

(2ab - 2ay0 - 2x0)2 - 4 (a2 + 1) (x0 + (b - y0)2 - r2) = 0

3)有两种解决方案

如果存在两种解决方案,例如xi和xj,则可能存在重叠。但是,对于凹多边形,这是不确定的。

要检查是否确实有重叠,必须检查相交是否发生在线段上。

这很简单。假设您的顶点位于点(x1,y1)和(x2,y2)之间,那么只有当……

x1 < xi < x2

或者…

x1 < xj < x2

在任何其他情况下,交集发生在顶点的延续上,而不是顶点本身。

如果上述条件之一成立,那么只有这样,你才能知道你的圆在多边形外漏了。

最终侧围:凹面边缘

还有一个封面要覆盖。如上所述,触摸多边形是可以的,因此有一个最终的没有被上面覆盖的核心:触摸一个凹边。

凹边是内角大于180°的边。因此,每当有多边形的交集时,如果相交发生在凹的边上,则要忽略它。

所有这些都适用于任何多边形,而不仅仅是三角形和六边形。


方法1:简单,但不精确

您已经实现了检查点是否在多边形内的算法。那么,为什么不把圆近似为等边多边形呢?你只需检查圆的16或64或256点。

方法2:更复杂,但更精确

  • 找到多边形每边的法向量(你可以很容易地计算它)。
  • 用这个法向量求圆心到边的距离(直线相交也是一个简单的任务)。
  • 如果距离小于圆的半径,则圆在多边形之外。
  • 否则,如果每边到其法向点的距离大于或等于圆的半径,那么圆就在里面。
  • image