如何检查一个圆是不是位于凸多边形内

Posted

技术标签:

【中文标题】如何检查一个圆是不是位于凸多边形内【英文标题】:How to check if a circle lies inside of convex polygon如何检查一个圆是否位于凸多边形内 【发布时间】:2014-09-06 14:39:54 【问题描述】:

我想检查一个圆是否相交或位于凸多边形内。我找到了一种检测点是否在多边形内的绝妙方法(来自here):

        public boolean insidePolygon(Vector2 [] vertices, Vector2 p)
        
            int i, j;
            boolean c = false;
            int nvert = vertices.length;
            for (i = 0, j = nvert - 1; i < nvert; j = i++)
            
                if (((vertices[i].Y > p.Y) != (vertices[j].Y > p.Y)) &&
                 (p.X < (vertices[j].X - vertices[i].X) * (p.Y - vertices[i].Y) / (vertices[j].Y - vertices[i].Y) + vertices[i].X))
                    c = !c;
            
            return c;
        

这对于单个点非常有效,但是我们有什么办法可以修改它来检查具有给定半径的圆是否在多边形内?我想这是可能的,因为圆实际上是一个点但更大,但我仍然没有成功......

【问题讨论】:

在几何上,圆强调只是“一个点,而是一个更大的点”。一个点有零维,一个圆有两个。您的问题有点类似于多边形边缘类似于光线的光线追踪“光线-球体相交”测试 - 试试看。 目前我正在处理圆圈相交并分别位于内部的情况。我只是好奇这种方法是否可以以某种方式扩展到同时涵盖这两种情况。但我必须承认,我所说的“圆就像一个点”有点幼稚…… 我认为这个问题的答案可能取决于你的多边形是否保证是凸包。啊 - 我看到你在问题中这么说......嗯。 【参考方案1】:

我可以想到两种方法来做到这一点:

第一种方式: 1) 计算圆心到每个边和每个顶点的距离,找到最小和最大距离,分别记为 Dmin 和 Dmax。 2) 使用 insidePolygon() 函数检查圆的中心是否位于多边形内。 3) 如果 ( R > Dmax ) 则圆包围了多边形。 如果 ( Dmin 如果( R 如果(R

我不得不承认,这与 insidePolygon() 使用的原始算法几乎没有任何关系。

第二种方式: 将多边形向内偏移距离 = 圆的半径。如果生成的多边形仍然是有效的多边形(即不是自相交的)并保持相同的顶点遍历方向,请检查圆的中心是否在偏移多边形内。如果是,则圆在原始多边形内。

第二种方法更接近原始算法,因为它向内偏移了圆的半径量,因此实际上将圆缩小到一个点。但是,在实现方面,第一种方法可能更容易。

【讨论】:

【参考方案2】:

有很多方法可以在数学上做到这一点,但我的做法是使用 Area 类。 这可能不是性能方面最有效的方法,但速度足以满足我的需求,而且由于我不是数学专家,所以没有数学部分是一个加号:)

public bool polygonContains circle (Shape poly, Shape circle)
    Area p = new Area(poly);
    if (!p.contains(circle.center)) return false;
    Area a = new Area(poly);        
    Area c = new Area(circle);
    a.add(c);
    //get the pathiterator of a and one for area p and compare the points they return
    // if there is a point in a not in p, it means circle jets out of polygon so return false.
    //if you care about the circle touching the inside of the polygon then 
    Area m = new Area(poly);
    Area s = m.substract(c);
    //repeat the pathiterator comparison for p and s , if there is a point in s not found in a
    //it means the circle touched the edge of the polygon return the value you see fit.
    return true;

【讨论】:

以上是关于如何检查一个圆是不是位于凸多边形内的主要内容,如果未能解决你的问题,请参考以下文章

斯威夫特:多边形中的点?如何检查用户的位置是不是在 Geo-JSON 多边形内?

POJ 1584 /// 判断圆(点)在多边形内 判断凸包

检查点是不是在多边形内

确定一个点是不是位于传单多边形内

非凸多边形内的最大圆

检查点是不是位于(或靠近)凸多边形边缘