Quickhull点未按正确顺序返回

时间:2015-05-04 23:03:17

标签: c# algorithm convex

我实现了以下页面中的快速船体代码:

http://www.ahristov.com/tutorial/geometry-games/convex-hull.html

算法返回凸包的正确点,但它没有以正确的三角顺序返回它们。由于这些点没有任何有意义的顺序,我不能用它们来绘制线条,因此也就是船体本身。

例如,当我使用以下几点运行算法时

 (2,5) (9,2) (1,8) (0,5) (3,3)

我希望他们返回的正确顺序是:

 (0,5) (1,8) (9,2) (3,3)

相反,快速船体算法会像这样返回它们:

 (1,8) (0,5) (3,3) (9,2)

任何人都可以帮助我

1 个答案:

答案 0 :(得分:1)

如果无法修改算法以按正确的顺序返回它们,您可以计算返回点的centroid(将它们全部加起来除以计数,质心一个凸包将始终位于船体内部,然后计算从质心到每个点的角度,如下所示:

point.angle = atan2(point.y - centroid.y, point.x - centroid.x);

然后根据角度对点列表进行排序。

此外,这部分C#代码与Java不匹配:

    // Recursively proceed with new sets
    HullSplit(minPt, farthestPt, leftSetMinPt, ref hull);
    HullSplit(maxPt, farthestPt, leftSetMaxPt, ref hull);
    // should be:
    // HullSplit(farthestPt, maxPt, leftSetMaxPt, ref hull);

Java是:

    hullSet(A,P,leftSetAP,hull);
    hullSet(P,B,leftSetPB,hull);

此外,与Java相比,您已经有效地扭转了线点测试的迹象:

public int pointLocation(Point A, Point B, Point P) {
   int cp1 = (B.x-A.x)*(P.y-A.y) - (B.y-A.y)*(P.x-A.x);
   return (cp1>0)?1:-1;
}

if (pointLocation(A,B,p) == -1)  // tests for negative
if (pointLocation(A,P,M)==1) { // tests for positive
if (pointLocation(P,B,M)==1) { // tests for positive

C#:

private static bool IsAboveLine(Point a, Point b, Point pt)
{
    var result = ((b.X - a.X) * (pt.Y - a.Y))
                -((b.Y - a.Y) * (pt.X - a.X));

    return (result > 0) ? true : false;
}

if (IsAboveLine(minPt, maxPt, pt))  // tests for positive
if (!IsAboveLine(minPt, farthestPt, set.ElementAt(i)))  // tests for negative
if (!IsAboveLine(farthestPt, maxPt, set.ElementAt(i)))  // tests for negative