检测凸多边形的极值点

Posted

技术标签:

【中文标题】检测凸多边形的极值点【英文标题】:Detect extreme points of a convex polygon 【发布时间】:2015-08-11 18:12:00 【问题描述】:

如何从确定的点看凸多边形的极值点?我试图通过点角度来做这个,越来越小的角度是极值点,但是当观察者更接近点时,这是无效的。

这是我的代码:

Vec2* bigger = &points[0]; // pointer to point with bigger angle
Vec2* smaller = &points[0]; // pointer to point with smaller angle

Vec2 observer = rayCenter;

// iterate through all points of polygon
for(unsigned u = 0 ; u < points.size() ; u++)

    Vec2 distance = observer - points[u];

    if(distance.angle() < (observer - *smaller).angle())
        smaller = &points[u];
    if(distance.angle() > (observer - *bigger).angle())
        bigger = &points[u];

结果:

其中蓝线是排除点和黄色理想点。 有没有解决这个问题的最佳方法?

对不起我的英语。

【问题讨论】:

【参考方案1】:

多边形顶点A对于观察者的给定位置是极端,如果多边形的所有其他点观察者的同一侧 -to-A 线(或者,可能位于该线上)。

如果已知多边形是凸的,那么标准就大大简化了。无需分析多边形的所有个其他点。通过分析其两个直接邻居的位置,可以轻松识别极值点。

如果A 是我们的候选点并且PN 是它在多边形中的相邻点(上一个和下一个),那么A 是一个极值点当且仅当PN 都位于在观察者到 A 线的同一侧。

vec_of_A = A - observer; // observer-to-A vector
vec_of_P = P - observer;
vec_of_N = N - observer;

productP = vec_of_A.x * vec_of_P.y - vec_of_A.y * vec_of_P.x;
productN = vec_of_A.x * vec_of_N.y - vec_of_A.y * vec_of_N.x;

if (sign(productP) == sign(productN))
  // A is an extreme point
else
  // A is not an extreme point

如果P 和/或N 恰好位于观察者到A 线上(取决于您在这种情况下认为极端的点),则需要做出一些额外的决策。

【讨论】:

【参考方案2】:

使用现有凸包中的点加上观察点计算新的凸包。在新的凸包中,与观察点相邻的点是您的“极端”点。

Here 是一个 matlab 实现。下面是一个示例输出,其中蓝点是观察点,绿色多边形是红点的凸包。实现返回点 (0,0) 和 (2,0)。

【讨论】:

【参考方案3】:

您不应该直接比较角度,因为存在 360° 环绕。

更喜欢通过计算观察者和两个点形成的三角形的带符号面积来测试“这个点更靠左”或“靠右”。

【讨论】:

以上是关于检测凸多边形的极值点的主要内容,如果未能解决你的问题,请参考以下文章

检测地理位置是不是在复杂多边形中

基于C#的多边形冲突检测

SQL Server 2014 在多边形中找到一个点

opencv如何读取多边形区域内的像素值?

OpenCV学习三十三:pointPolygonTest 检测点是否在轮廓内

检测 CGPoint 是不是在多边形内