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

时间:2013-08-22 17:41:23

标签: c# wpf language-agnostic 3d computational-geometry

你好,我有一个问题,我认为很难解决,我到处寻找解决方案,但我没有找到任何东西。

我想从点列表中绘制个人资料。

我的问题是:

  1. 我有一个来自文本文件的Points3D列表,它们不是任何顺序,就像随机点一样。当然我把它们添加到List。我使用小型3D椭圆在3D空间中绘制这些点。到目前为止一切顺利。
  2. 现在我想绘制一个遍历列表中所有点的3D样条线。所以我创建了Spline3D类,它使用三次插值来确定文本文件中给定点之间曲线点的位置。在我的样条中,我计算出400个新点,然后我在每对点之间绘制小的3D圆柱:点i和点i + 1在它们之间有小圆柱+圆柱体正确旋转所以一切看起来像真正的样条(在理论)。
  3. 主要问题是点是无序的,所以如果我只是这样做,我会得到这样的样条:

    http://img5.imageshack.us/img5/4659/2b61.jpg

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

    http://img194.imageshack.us/img194/9016/hv8e.jpg

    http://img5.imageshack.us/img5/659/nsz1.jpg

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

    1. 以某种顺序放置点,然后将它们添加到Spline3D并计算样条曲线。

    2. 以其他方式计算样条曲线,这可能会以某种方式导致有序点,所以基本上它仍然会让我达到1.

    3. 所以我尝试了一些重新排序方法。

      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
      

      这是我的第一个想法,我认为这将成为我问题的最终解决方案。我从点列表中随机选择一个点,这一点成为样条曲线的第一个点。然后我找到了与前一点最接近的点,我将他添加到样条曲线并从列表中删除等等......

      http://img18.imageshack.us/img18/3650/mik0.jpg

      http://img706.imageshack.us/img706/3834/u97b.jpg

      可悲的是,有时(特别是我的轮廓边缘附近)向下靠近距离靠近点,所以花键变得弯曲。

      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());
      

      基本上我使用旅行商问题算法来确定所有点的最短样条(最短路径)。遗憾的是,这个问题是NP-Hard,所以为了获得良好的性能,我会使用一些启发式方法。

      http://img198.imageshack.us/img198/714/xiqy.jpg

      http://img839.imageshack.us/img839/9530/exnu.jpg

      Spline看起来比1.a好,但仍然不够。

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

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

      那么我怎么能解决这个问题呢?有什么想法吗?

1 个答案:

答案 0 :(得分:1)

听起来你正在寻找数据集的Concave Hull

不幸的是,我不知道任何预先计算的算法,但该链接引用了另一个开发人员开始的论文,以及一些示例代码,所以这可能会帮助您朝着正确的方向前进。 / p>