C++ 将圆或样条曲线拟合到一组三维点中

C++ 将圆或样条曲线拟合到一组三维点中,c++,c,geometry,least-squares,C++,C,Geometry,Least Squares,我有一些3D点,大致但清晰地形成了一个圆的一段。我现在必须确定最适合所有点的圆。我认为必须有某种最小二乘法的最佳拟合,但我不知道如何开始。 点按其在圆上的位置进行排序。我还估计了每个点的曲率。 我需要圆的半径和平面。 我必须使用c/c++或使用外部脚本。您可以使用(PCA)将坐标从三维映射到二维 计算主成分分析并将数据投影到第一个主成分上。然后,您可以使用任何2D算法来查找圆心及其半径。一旦找到/安装了这些,就可以将中心投影回三维坐标中 由于您的数据是有噪声的,在您挤出的第三维度中仍会有一些数据

我有一些3D点,大致但清晰地形成了一个圆的一段。我现在必须确定最适合所有点的圆。我认为必须有某种最小二乘法的最佳拟合,但我不知道如何开始。 点按其在圆上的位置进行排序。我还估计了每个点的曲率。 我需要圆的半径和平面。 我必须使用c/c++或使用外部脚本。

您可以使用(PCA)将坐标从三维映射到二维

计算主成分分析并将数据投影到第一个主成分上。然后,您可以使用任何2D算法来查找圆心及其半径。一旦找到/安装了这些,就可以将中心投影回三维坐标中


由于您的数据是有噪声的,在您挤出的第三维度中仍会有一些数据,但请记住,PCA选择该维度是为了最小化数据丢失量,即通过最大化前两个组件中表示的数据量,所以你应该是安全的。

这种数据拟合的一个好算法是(随机样本一致性)。您可以在链接中找到一个很好的描述,因此这只是重要部分的简短概述:

在您的特殊情况下,模型将是3D圆。要建立此模型,请从集合中拾取三个随机非共线点,计算它们嵌入的超平面(叉积),将随机点投影到该平面,然后应用常用的二维圆拟合。通过这个你可以得到圆心,半径和超平面方程。现在很容易通过每个剩余点检查支撑。支撑可以表示为与圆的距离,圆由两部分组成:与平面的正交距离和与平面内圆边界的距离

编辑:
与普通最小二乘法(LS)相比,我更喜欢RANSAC的原因是它在严重异常值的情况下具有优越的稳定性。下图显示了LS与RANSAC的对比示例。理想模型线是由RANSAC创建的,而虚线是由LS创建的。

可以说最简单的算法是最小二乘曲线拟合。 您可能需要检查, 或者看看类似的问题,例如

不过,我宁愿使用一个库来做这件事。

你已经试过了吗?没有,只是在网上搜索了最小二乘拟合圆。不过,我发现的大多数算法都是二维的,所以没用。你可以将二维算法移植到三维中。有两个变量:圆心及其半径。圆心转换为三个坐标,因此总体而言,您希望使用最小二乘法优化四个变量(三个坐标和半径)。@alestanis实际上,它是六个实变量:圆心和圆的法向量。-但这并不是一个真正的问题,更复杂的是把一个点从一个圆到三维的距离的定义推广到一个球体,我现在知道了。也许有一种简单的方法可以在第一步中检测出我们在哪个平面上,旋转坐标,然后在第二步中仅使用两个坐标找到圆?这假设所有点都在平面内,但问题涉及到噪声数据,因此您的解决方案很大程度上取决于您对初始三个点的选择。否。我所描述的只是一次RANSAC。该算法执行大量这样的运行,并以最佳支持输出模型,从而输出最适合含噪数据的圆。但这是在提供的链接中描述的。是的,但如果生成的圆弧不在由三个采样点构成的平面内,它仍然无法在最小二乘意义上找到最优解。这样的启发式很可能会提供一个好的解决方案,但不一定是最好的,这不是启发式。根据定义,三维中的圆弧嵌入在平面中:)是的,但您缺少一点:RANSAC启发式方法将只查看数据集中跨越三个点的平面。这是一组有限的平面,不能保证最优解的平面在这个平面集中。你知道这样一个库吗?这个问题的答案提到了GNU gsl。