Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 顺时针排序点列表_C#_Algorithm_Sorting_Geometry_Computational Geometry - Fatal编程技术网

C# 顺时针排序点列表

C# 顺时针排序点列表,c#,algorithm,sorting,geometry,computational-geometry,C#,Algorithm,Sorting,Geometry,Computational Geometry,我遇到了问题,不知道如何解决 我试图对点列表进行排序,以便所有点都能形成一条路径。到目前为止,我所做的是计算列表中所有点的中心点,然后使用排序所基于的代码。以下是借用的代码片段: public int Compare(Point3D pointA, Point3D pointB) { if (pointA.X - CenterPoint.X >= 0 && pointB.X - CenterPoint.X < 0) return 1;

我遇到了问题,不知道如何解决

我试图对点列表进行排序,以便所有点都能形成一条路径。到目前为止,我所做的是计算列表中所有点的中心点,然后使用排序所基于的代码。以下是借用的代码片段:

public int Compare(Point3D pointA, Point3D pointB)
{
    if (pointA.X - CenterPoint.X >= 0 && pointB.X - CenterPoint.X < 0)
        return 1;
    if (pointA.X - CenterPoint.X < 0 && pointB.X - CenterPoint.X >= 0)
        return -1;

    if (pointA.X - CenterPoint.X == 0 && pointB.X - CenterPoint.X == 0)
    {
        if (pointA.Y - CenterPoint.Y >= 0 || pointB.Y - CenterPoint.Y >= 0)
           if (pointA.Y > pointB.Y)
               return 1;
            else return -1;
        if (pointB.Y > pointA.Y)
            return 1;
        else return -1;
    }

    // compute the cross product of vectors (CenterPoint -> a) x (CenterPoint -> b)
    double det = (pointA.X - CenterPoint.X)*(pointB.Y - CenterPoint.Y) -
                     (pointB.X - CenterPoint.X)*(pointA.Y - CenterPoint.Y);
    if (det < 0)
        return 1;
    if (det > 0)
        return -1;

    // points a and b are on the same line from the CenterPoint
    // check which point is closer to the CenterPoint
    double d1 = (pointA.X - CenterPoint.X)*(pointA.X - CenterPoint.X) +
                    (pointA.Y - CenterPoint.Y)*(pointA.Y - CenterPoint.Y);
    double d2 = (pointB.X - CenterPoint.X)*(pointB.X - CenterPoint.X) +
                    (pointB.Y - CenterPoint.Y)*(pointB.Y - CenterPoint.Y);
    if (d1 > d2)
        return 1;
    else return -1;
}
public int Compare(点3D点A、点3D点B)
{
如果(pointA.X-CenterPoint.X>=0&&pointB.X-CenterPoint.X<0)
返回1;
if(pointA.X-CenterPoint.X<0&&pointB.X-CenterPoint.X>=0)
返回-1;
if(pointA.X-CenterPoint.X==0&&pointB.X-CenterPoint.X==0)
{
if(pointA.Y-CenterPoint.Y>=0 | | pointB.Y-CenterPoint.Y>=0)
如果(点A.Y>点B.Y)
返回1;
否则返回-1;
如果(点B.Y>点A.Y)
返回1;
否则返回-1;
}
//计算向量的叉积(中心点->a)x(中心点->b)
双det=(pointA.X-CenterPoint.X)*(pointB.Y-CenterPoint.Y)-
(点B.X-中心点X)*(点A.Y-中心点Y);
如果(det<0)
返回1;
如果(det>0)
返回-1;
//点a和b与中心点在同一条线上
//检查哪个点更靠近中心点
双d1=(pointA.X-CenterPoint.X)*(pointA.X-CenterPoint.X)+
(pointA.Y-CenterPoint.Y)*(pointA.Y-CenterPoint.Y);
双d2=(pointB.X-CenterPoint.X)*(pointB.X-CenterPoint.X)+
(点B.Y-中心点Y)*(点B.Y-中心点Y);
如果(d1>d2)
返回1;
否则返回-1;
}
在某些情况下,它工作正常,但有时会产生奇迹,请参见附图,黑点是计算出的中心点:

在图A中,一切正常,但如果我决定向上移动形成两条水平线的点,我会遇到以下情况:


绿线是它应该是什么样子,黑线是它真正的样子,我不明白为什么我会这样。我也尝试了
atan()
解决方案,但结果相同。非常感谢您的帮助。

在您的两个示例中,按顺时针顺序排列的点都很好。但对于第二个例子,它的方法并不合适。顺时针算法仅适用于凸面图形

这是不支持的图形示例,没有可用的中心点


因此,如果您有一些点集,但不知道如何链接它们,也不知道有关图形的任何信息,则无法恢复原始图形。

我认为将计算出的中心点的位置添加到图片中会很有趣。您的主要任务是什么?我有一个点列表,希望绘制通过这些点的路径。不幸的是,它们没有被排序,并且给出了错误的结果。因此,我试图自己对它们进行分类@一般情况下,如果你不知道点的顺序,你就不能画出正确的路径。在你的第二张图片上,路径中的点的顺序是围绕中心点顺时针的。一旦你有了中心点,你就可以计算你的点和中心点之间的角度,然后用它来排序。所以你说如果我有凹多边形,无法对点进行排序以绘制正确的路径?@niks:第一个多边形也是凹的。当中心点位于核中时,该算法有效。凸多边形是星形的,其核心是整个多边形,因此顺时针排序对它们有效。如果你想办法将第二个多边形的中心移动到T形条交叉的地方,你也可以对第二个多边形使用顺时针排序。@MOehm,没有办法使算法适用于所有情况。@niks,如果你有一些点集,但不知道如何链接它们,对图形一无所知,无法还原原始图形。但可能您知道一些有关图形或点的规则?@MOehm不幸的是,多边形的形状和大小不同,因此无法调整每个多边形的中心。看来我得另想办法解决我的问题了。