当前位置: 首页 > news >正文

Open CASCADE学习|读取点集拟合样条曲线(续)

问题

上一篇文章已经实现了样条曲线拟合,但是仍存在问题,Tolerance过大拟合成直线了,Tolerance过大头尾波浪形。


正确改进方案

1️⃣ 核心参数优化

通过调整以下参数控制曲线平滑度:

Standard_Integer DegMin = 3;    // 最低阶数(建议≥3)
Standard_Integer DegMax = 5;    // 最高阶数(过高易过拟合)
Standard_Real Tolerance = 1e-3;  // 容差(需根据点集坐标范围调整)
GeomAbs_Shape Continuity = GeomAbs_C2; // 连续性(C2更平滑)
2️⃣ 构造拟合器时直接指定参数
// 使用构造函数直接传递参数(正确方法)
Geom2dAPI_PointsToBSpline approximator(
    pointsArray,    // 点集
    DegMin,         // 最小阶数
    DegMax,         // 最大阶数
    Continuity,     // 连续性
    Tolerance       // 容差
);
3️⃣ 抑制波浪形的替代方法
  • 增大容差 (Tolerance)
    逐步增加 Tolerance 值,允许曲线偏离原始点,强制忽略高频波动(头尾噪声)。例如,若点集分布在 [0, 100] 范围内,可将 Tolerance 设为点集总范围的 2-5%(如 2.0~5.0)。

  • 提高连续性 (Continuity)
    使用 GeomAbs_C2 连续性(二阶连续),强制曲线在连接处更平滑,抑制局部抖动。

  • 限制曲线阶数 (DegMax)
    DegMax 设为较低值(如 5),避免高阶曲线过度拟合噪声。


分段控制替代方案

若需隐式控制分段数,可通过以下方法间接实现:

// 通过容差和连续性间接影响分段数
approximator.Init(pointsArray, DegMin, DegMax, Continuity, Tolerance);
// 注:Init() 方法允许重新初始化参数

数据预处理(关键步骤)

对波动较大的头尾数据进行滤波处理:

#include <algorithm>
#include <vector>

// 滑动平均滤波函数(窗口大小=3)
std::vector<gp_Pnt2d> SmoothPoints(const std::vector<gp_Pnt2d>& input, int windowSize = 3) {
    std::vector<gp_Pnt2d> output;
    for (size_t i = 0; i < input.size(); ++i) {
        double sumX = 0.0, sumY = 0.0;
        int count = 0;
        int start = std::max(0, (int)i - windowSize/2);
        int end = std::min((int)input.size()-1, (int)i + windowSize/2);
        for (int j = start; j <= end; ++j) {
            sumX += input[j].X();
            sumY += input[j].Y();
            count++;
        }
        output.emplace_back(sumX/count, sumY/count);
    }
    return output;
}

// 使用平滑后的点集
std::vector<gp_Pnt2d> smoothPoints = SmoothPoints(pointsVec, 3);

完整代码修正

#include <Geom2dAPI_PointsToBSpline.hxx>
#include <TColgp_Array1OfPnt2d.hxx>

Handle(Geom2d_BSplineCurve) FitCurve2D(const std::vector<gp_Pnt2d>& pointsVec) {
    if (pointsVec.size() < 2) return nullptr;

    // 转换为OpenCASCADE数组(索引从1开始)
    TColgp_Array1OfPnt2d pointsArray(1, pointsVec.size());
    for (int i = 0; i < pointsVec.size(); ++i) {
        pointsArray.SetValue(i + 1, pointsVec[i]);
    }

    // 设置拟合参数
    Standard_Integer DegMin = 3;
    Standard_Integer DegMax = 5;
    Standard_Real Tolerance = 2.0;  // 根据点集范围调整
    GeomAbs_Shape Continuity = GeomAbs_C2;

    // 创建拟合器
    Geom2dAPI_PointsToBSpline approximator(
        pointsArray, DegMin, DegMax, Continuity, Tolerance
    );

    if (approximator.IsDone()) {
        return approximator.Curve();
    }
    return nullptr;
}

参数调整建议

现象解决方案参数调整方向
头尾波浪形严重增大容差,降低曲线自由度Tolerance ↑, DegMax ↓
曲线过于僵硬减小容差,允许更多细节Tolerance ↓, DegMax ↑
连接处不光滑提高连续性要求Continuity → GeomAbs_C2

验证方法

  1. 可视化检查:将拟合曲线与原始点绘制在同一坐标系,观察趋势是否符合。
  2. 误差分析:计算曲线到点的最大偏差:
    Standard_Real maxError = approximator.MaxError();
    std::cout << "Max fitting error: " << maxError << std::endl;
    
  3. 参数迭代:若误差远小于 Tolerance,说明容差设置过大,可适当减小。

调整前的结果:

调整后的结果:

通过以上方法,有效抑制头尾波浪形,使曲线贴合整体趋势。

相关文章:

  • 碰一碰发视频源头开发技术服务商
  • CentOS 7 yum 无法安装软件的解决方法
  • oracle 快速创建表结构
  • C语言基础20
  • 基于SpringBoot的“智慧医疗采购系统”的设计与实现(源码+数据库+文档+PPT)
  • 【题解】AtCoder AT_abc400_c 2^a b^2
  • d202547
  • AF3 OpenFoldMultimerDataModule类解读
  • 【零基础入门unity游戏开发——动画篇】Animation动画窗口,创建编辑动画
  • uniapp微信小程序地图marker自定义气泡 customCallout偶尔显示不全解决办法
  • 本地大模型构建个人知识库(Ragflow)
  • Oracle序列介绍
  • Web开发:常用 HTML 表单标签介绍
  • 数据类型与判断
  • 【后端开发面试题】每日 3 题(三十)
  • CentralCache
  • 登录窗口布局
  • 具身智能零碎知识点(一):深入解析Transformer位置编码
  • oracle 包的管理
  • ffmpeg提取字幕
  • 网站建设 公司 常见问题/网站排名推广软件
  • 手机版企业网站h5/株洲百度seo
  • 怎么做 废旧回收网站/谷歌浏览器app
  • 网站建设项目外包/培训课程总结
  • 虎门微网站建设/营销渠道分为三种模式
  • 天河做网站哪家好/潍坊网站建设