检测凸多边形的极值点
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
是我们的候选点并且P
和N
是它在多边形中的相邻点(上一个和下一个),那么A
是一个极值点当且仅当P
和N
都位于在观察者到 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° 环绕。
更喜欢通过计算观察者和两个点形成的三角形的带符号面积来测试“这个点更靠左”或“靠右”。
【讨论】:
以上是关于检测凸多边形的极值点的主要内容,如果未能解决你的问题,请参考以下文章