C++ 创建平滑线以在三维中连接N个点

C++ 创建平滑线以在三维中连接N个点,c++,graphics,spline,C++,Graphics,Spline,我在三维空间中有N个点。我需要用一条线把他们连接起来。然而,如果我用一条简单的线来做这件事,它是不平滑的,看起来很难看 我目前的方法是使用贝塞尔曲线,对4个点使用DeCasteljau算法,并对数据集中的每组4个点运行该算法。然而,问题是,因为我分别在1-4、5-8、9-12等点上运行它,所以4-5、8-9等点之间的线并不平滑 我还寻找其他方法;特别是我发现了关于Catmull Rom样条曲线,它似乎更适合我的目的,因为曲线通过所有控制点,不像Bezier曲线。所以我几乎开始实现它,但后来,我在

我在三维空间中有N个点。我需要用一条线把他们连接起来。然而,如果我用一条简单的线来做这件事,它是不平滑的,看起来很难看

我目前的方法是使用贝塞尔曲线,对4个点使用DeCasteljau算法,并对数据集中的每组4个点运行该算法。然而,问题是,因为我分别在1-4、5-8、9-12等点上运行它,所以4-5、8-9等点之间的线并不平滑

我还寻找其他方法;特别是我发现了关于Catmull Rom样条曲线,它似乎更适合我的目的,因为曲线通过所有控制点,不像Bezier曲线。所以我几乎开始实现它,但后来,我在那个网站上看到,这个公式可以“假设控制点的间距是均匀的”。我的问题不是这样的

所以,我的问题是,我应该使用什么方法——贝塞尔,卡穆尔Rom,或者完全不同的东西?如果是贝塞尔,那么如何修复4-5、8-9等之间的不平滑度。?如果是Catmull Rom,如果点的间距不均匀,为什么公式不起作用?我需要什么

编辑:我现在非常确定我想要的是Catmull Rom样条曲线,因为它通过每个控制点,这对我的应用程序是一个优势。因此,我想回答的主要问题是,为什么我提供的链路上的公式不适用于非等距控制点

谢谢。

通过高斯过程可以找到一条有意义的线(虽然不是最简单的评估)。您设置(或推断)希望线在其上变化的长度比例(即线的平滑度),然后GP线是通过给定长度比例的数据最可能的线。如果不介意线不通过数据点,可以向模型添加噪波

这是一种很好的插值方法,因为您还可以获得直线的标准偏差。当Vacity中没有太多数据时,该行变得更加不确定


您可以在David MacKay的《信息理论、推理和学习算法》第45章中阅读这些内容,您可以从作者的网站下载。

一个解决方案是维基百科的下一页:/Bézier_曲线,检查N个控制点的广义方法。

两个解决方案:

  • 使用B样条曲线。这是Bezier曲线的推广(Bezier曲线是一条没有内部节点的B样条曲线。)

  • 使用三次样条曲线。三次样条曲线特别容易计算。三次样条曲线在控制点的零、一阶和二阶导数上是连续的。三阶导数,即立方项,在控制点处存在不连续性,但很难看到这些不连续性


B样条曲线和三次样条曲线之间的一个关键区别是,三次样条曲线将通过所有控制点,而B样条曲线不会。思考的一种方式是:这些内部控制点只是对B样条曲线的建议,但对三次样条曲线是强制性的。

您的产品线的用途是什么?你只是想要一条令人赏心悦目的线条,还是更具数量意义的线条。例如,假设(比如)高斯噪声,你可能想要通过数据点得到最可能的曲线?@Tom:基本上,我是通过物理模拟得到这些点的,线的平滑只是为了显示最终结果,所以我想这只是为了讨人喜欢:)@houbysoft在这种情况下,你为什么要自己编写绘图仪,为什么不直接输出数据并绘图,比如说gnuplot。@汤姆:最终结果将显示在一个由多台计算机操作的特殊3D房间中,这需要一个特定的应用程序来完成工作。此外,我需要为绘图仪添加一些交互性,比如与头部跟踪设备通信等。重点是,应用程序非常具体,不仅仅是显示线条,因此gnuplot无法工作。您希望线条通过每个点并且平滑,还是只通过点而不通过所有人,如果第二种情况是,谷歌为“多维回归分析”添加了这个答案,三次样条曲线甚至不需要像OP所说的控制点间距。您只需要一个好的参数化(弧长,如果可以)来确保插值点的均匀分布。特别是检查基数样条曲线(Catmull Rom是其中的一个子类),它们具有可调整的曲率(张力),并且是用于图形的一个很好的三次样条曲线。@Ron Warholic:啊,所以基本上,如果我使用非等距点的公式,唯一的问题是,如果我总是为每对数据点绘制新曲线的10个点,有时这些新点不会等距分布,对吗?差不多。但是,如果根据控制点之间的弧长参数化插值,则会得到间距非常理想的点,但实现起来可能有点困难。