C++ 对向量中的点进行排序以形成连接

C++ 对向量中的点进行排序以形成连接,c++,sorting,vector,coordinates,C++,Sorting,Vector,Coordinates,我得到了一个向量,有n行,点的xy坐标。这些点构成给定CAD模型的连接。现在我想恢复模型的连续性。所以我尝试用atan2函数对点进行排序。 这是我用来对点进行排序的代码 std::sort(matrix.begin(), matrix.end(), sort1); matrix.erase(std::unique(matrix.begin(), matrix.end(), compare2),matrix.end()); matrix.push_back(std::vector<dou

我得到了一个向量,有n行,点的xy坐标。这些点构成给定CAD模型的连接。现在我想恢复模型的连续性。所以我尝试用atan2函数对点进行排序。 这是我用来对点进行排序的代码

std::sort(matrix.begin(), matrix.end(), sort1);

matrix.erase(std::unique(matrix.begin(), matrix.end(), compare2),matrix.end());

matrix.push_back(std::vector<double>(3, 0));
如您所见,当x和y坐标改变时,atan2与其他值保持在相同的范围内。对我来说,这就是问题所在,为什么我的连接不正确。我是否必须向排序函数中添加一些内容才能获得正确的结果


我的一个想法是对坐标进行排序,不仅根据atan2,而且还根据点之间的向量长度(最低atan2)和所有其他点。但这是我的问题。我会先按atan2排序,然后再按长度排序。但是第二个排序过程将破坏第一个排序函数的洞结果。

atan2
显然在一般情况下没有帮助。它主要适用于凸面图形。考虑一个带有(0,0)内部和相邻矩形的窄矩形,并尝试用它们的ATAN2排序它们的点。
您是否尝试过在集合中绘制点,然后作为迭代步骤查找最近的尚未绘制点?

如果您仅处理曲线,则建议使用以下算法:

  • 定义角度范围R
  • 取起始点A,将其标记为已访问
  • 找到最靠近AB,将其标记为已访问
  • 计算向量[AB形成的方向
  • 在角度范围R中,找到距离B最近的未访问点C,并将其标记为已访问
  • 转到步骤4,将B作为AC作为B

  • 这不是一个最终的解决方案,但它应该能够找到基本曲线和一些多边形。使用更宽的角度范围R可以近似更多的曲线。

    因此,基本上,atan2不是正确的排序方法,您需要知道如何排序以获得任何给定点集的轮廓。这似乎与数学更相关。对我来说,atan2似乎是对向量进行排序的良好开端。但我想我需要的不仅仅是这一个函数来对整个向量进行排序。atan2执行循环扫描,这对有限的一组点来说是可以的,而不是对更复杂的轮廓或原点不在内部的轮廓。所以你的意思是我可以从按atan2对向量进行排序开始,搜索结果最低的点,并将此点用作我的新起点。从这一点开始,我将搜索最近的点,并将其添加为向量中的第二个点,然后再次使用该点作为起点。我将继续这个过程,直到到达向量中的最后一点?当然,但是排序在这里是完全不必要的(取任意点,旋转坐标轴,使其落在x轴上,因此它的atan2为0;你可以看到,排序在这里没有添加任何内容)。一个更复杂的算法涉及回溯:当你选择下一个点,但显然移动到下一个点时,速度向量的方向发生了太大的变化(超过pi/2是一个好的开始),你可能必须向后移动几个点,然后尝试另一种方法。最后,您可以通过所有点绘制一个闭合轮廓作为起点,然后执行几个优化步骤以减少弯曲:使用所有点处角速度变化的绝对值之和作为要最小化的函数,然后尝试交换相邻顶点以查看是否使函数的值变小。更简单的是,我认为最小化多边形长度就足够了,而且不会弄乱角度。
    bool sort1(vector<double> const& s1, vector<double> const& s2)
    {
        return atan2(s1[1],s1[0])<atan2(s2[1],s2[0]);
    } 
    
       x             y      z     atan2
    -5.44283    -1.94995    0   -2.79758
    -5.36969    -1.93228    0   -2.79617
    -5.33637    -1.92454    0   -2.79547
    -13.15      -4.76500    0   -2.79395
    -5.26308    -1.90750    0   -2.79389
    -5.22970    -1.90005    0   -2.7931
    -5.15626    -1.88364    0   -2.79134