【问题标题】: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];
}

结果:

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

对不起我的英语。

【问题讨论】:

    标签: c++ algorithm geometry


    【解决方案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° 环绕。

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

        【讨论】:

          猜你喜欢
          • 2017-03-28
          • 2013-04-25
          • 2013-07-11
          • 2013-05-26
          • 2011-05-09
          • 2015-08-17
          • 1970-01-01
          • 1970-01-01
          • 2017-09-29
          相关资源
          最近更新 更多