C# 如何通过无序的点列表3D绘制闭合样条线3D(闭合曲线3D)。如何安排点3d?

C# 如何通过无序的点列表3D绘制闭合样条线3D(闭合曲线3D)。如何安排点3d?,c#,wpf,language-agnostic,3d,computational-geometry,C#,Wpf,Language Agnostic,3d,Computational Geometry,你好,我有一个问题,我认为这是很难解决的,我一直在寻找解决办法,但我没有找到任何东西 我想从点列表中绘制轮廓 我的问题是: 我有一个文本文件中的点3d列表,它们没有任何顺序,就像随机点一样。当然,我把它们添加到了列表中。我用小的3D椭圆在3D空间中绘制这些点。到目前为止还不错 现在我想画一条穿过列表中所有点的三维样条曲线。所以我创建了Spline3D类,它使用三次插值来确定文本文件中给定点之间曲线点的位置。在我的样条曲线中,我计算了400个新点,然后我在每对点之间绘制了小的3D圆柱体:点I和点I

你好,我有一个问题,我认为这是很难解决的,我一直在寻找解决办法,但我没有找到任何东西

我想从点列表中绘制轮廓

我的问题是:

  • 我有一个文本文件中的点3d列表,它们没有任何顺序,就像随机点一样。当然,我把它们添加到了列表中。我用小的3D椭圆在3D空间中绘制这些点。到目前为止还不错
  • 现在我想画一条穿过列表中所有点的三维样条曲线。所以我创建了Spline3D类,它使用三次插值来确定文本文件中给定点之间曲线点的位置。在我的样条曲线中,我计算了400个新点,然后我在每对点之间绘制了小的3D圆柱体:点I和点I+1之间有一个小圆柱体+圆柱体正确旋转,所以所有东西看起来都像真实的样条曲线(理论上)
  • 主要问题是点是无序的,所以如果我只是这样做,我得到的样条线如下:

    在空间中绘制的原始点如下所示:

    所以我发现我有两个解决方案

  • 按某种顺序放置点,然后将它们添加到Spline3D并计算spline

  • 用另一种方法计算样条曲线,这可能会在某种程度上导致有序点,所以基本上它仍然会导致我得到1

  • 所以我尝试了一些重新排序的方法

    1。a) 点的最近邻

    int firstIndex = (new Random().Next(pointsCopy.Count));//0;//pointsCopy.Count / 2;//(new Random().Next(pointsCopy.Count));
    NPoint3D point = pointsCopy[firstIndex];
    pointsCopy.Remove(point);
    
    spline3D.addPoint(point.ToPoint3D());
    
    NPoint3D closestPoint = new NPoint3D();
    
    double distance;
    double nDistance;
    
    Point3D secondPoint = new Point3D();
    bool isSecondPoint = true;
    
    while (pointsCopy.Count != 0)
    {
        distance = double.MaxValue;
    
        for (int i = 0; i < pointsCopy.Count; i++)
        {
            nDistance = point.distanceToPoint(pointsCopy[i]);
            if (nDistance < distance)
            {
                distance = nDistance;
                closestPoint = pointsCopy[i];
            }
        }
        if (isSecondPoint)
        {
            isSecondPoint = false;
            secondPoint = closestPoint.ToPoint3D();
        }
    
        spline3D.addPoint(closestPoint.ToPoint3D());
        point = closestPoint;
        pointsCopy.Remove(closestPoint);
    }
    spline3D.addPoint(points[firstIndex].ToPoint3D()); //first point is also last point
    
    intfirstindex=(new Random().Next(pointsCopy.Count))//0;//点透视计数/2//(new Random().Next(pointsCopy.Count));
    NPoint3D点=点透视[第一索引];
    点透视。移除(点);
    spline3D.addPoint(point.ToPoint3D());
    NPoint3D closestPoint=新的NPoint3D();
    双倍距离;
    双重立场;
    Point3D secondPoint=新的Point3D();
    bool isSecondPoint=true;
    while(pointsCopy.Count!=0)
    {
    距离=double.MaxValue;
    for(int i=0;i
    这是我的第一个想法,我认为这将成为我问题的最终解决方案。我从点列表中随机选择一个点,这个点成为样条曲线的第一个点。然后我找到离上一点最近的点,我把他添加到样条曲线中,然后从列表中删除,等等

    不幸的是,有时(特别是在我的轮廓边缘附近)点向下比点靠近,所以样条曲线变得弯曲

    2。b) TSP

        distanceMatrix = new TSP.DistanceMatrix(pointsCopy, NPoint3D.distanceBetweenTwoPoints);
    int[] indexes = TSP.Algorithms.TSPgreedySearch(distanceMatrix);
    for (int i = 0; i < indexes.Length; i++)
        spline3D.addPoint(pointsCopy[indexes[i]].ToPoint3D());
    spline3D.addPoint(pointsCopy[indexes[0]].ToPoint3D());
    
    distanceMatrix=新的TSP.distanceMatrix(点透视,NPoint3D.Distanceween两点之间的距离);
    int[]index=TSP.Algorithms.TSPgreedySearch(距离矩阵);
    for(int i=0;i
    基本上,我使用旅行商问题算法来确定通过所有点的最短样条(最短路径)。不幸的是,这个问题是NP难的,所以为了获得好的性能,我使用了一些启发式算法

    样条线看起来比1.a中的更好,但仍然不够

    3。c) 使用两条样条线的一些奇怪方法

    我的一些朋友告诉我,我应该将轮廓分成两部分(上部和下部),然后计算并绘制两条样条曲线。可悲的是,我不知道怎么做,我的意思是,我不知道如何确定点应该在上半部分还是下半部分。请帮帮我


    那么我该如何解决这个问题呢?有什么想法吗?

    听起来你在寻找数据集的最新版本


    不幸的是,我不知道有任何预先封装的算法,但链接引用了另一位开发人员开始撰写的论文,以及一些示例代码,因此这可能会帮助您朝正确的方向发展。

    为什么您不能将数据整理好呢?文本文件来自一些我不太了解的软件,这只是软件输出它们的方式。这很好,但我不知道如何将其应用于3D。我应该如何计算角度?@PandaWoll:理论上,两个向量Va和Vb之间的角度是点(Va,Vb)/(| | Va | |*| Vb |)。不管这在这里有用与否。。。抱歉,我只是不确定我是否知道如何进一步处理它。@PandaWoll:说实话,你正在尝试获取一个3D点云,并将其从几个横截面区域转化为网格。如果有办法做到这一点,理论上几乎肯定是复杂的,而且是NP难的。我会先担心找到解决方案,然后再担心效率。