离散数据点NURBS曲线拟合算法

article/2025/8/21 9:16:47

问题描述:对于离散数据点集来说,其主要特征点一般可以描述原始曲线轨迹的基本形状。对于大量的离散数据点来说,提取主要的特征点后在进行曲线拟合,这样可以降低计算次数,极高拟合效率。

可以描述原始曲线几何形状的 特征点主要有反曲点、曲率极值点和弓高特征点。

提取主要特征点

反曲点:又称拐点,在数学上指改变曲线向上或向下方向的点,直观地说拐点是使切线穿越曲线的点(即连续曲线的凹弧与凸弧的分界点)。

对于离散的数据点,相邻两点的法向量夹角值若为\pi,则认为其凹凸性发生了变化。空间中每连续四个刀位点(Q_{j-1},Q_{j},Q_{j+1},Q_{j+2}),可以计算法向量V_{j},V_{j+1},如图1所示,并计算V_{j},V_{j+1}的夹角\theta_{V}。如果\theta_{V}>\theta_{max}(假设\theta_{max}=\pi/2),则曲线的凹凸性发生了变化,将该点作为反曲点,此时法向量V_{j},V_{j+1}的夹角为一个接近于\pi的值。通过遍历所有离散点,即可找到所有的反曲点。计算公式为:\begin{Bmatrix} V_{j} =Q_{j-1}\cdot Q_{j}\times Q_{j}\cdot Q_{j+1} \\ V_{j+1}=Q_{j}\cdot Q_{j+1}\times Q_{j+1}\cdot Q_{j+1} \end{Bmatrix},\theta_{V}=arccos(\frac{V_{j}\times V_{j+1}}{\left | V_{j} \right |\left | V_{j+1} \right |})

 

 图1 反曲点示意图

曲率极值点:本文采用圆弧估算法求解离散数据点的曲率,如图2所示,数据点Q_{i}处的曲率值\kappa _{i},可以通过求解过点Q_{i-1},Q_{i},Q_{i+1}的圆弧的曲率来求解,计算公式为:\kappa _{i}=\frac{2sin(\angle Q_{i-1}Q_{i}Q_{i+1}))}{\left | Q_{i-1} Q_{i+1}\right |}

图2 圆弧法估算曲率示意图

 在确定了离散数据点的反曲点之后,遍历所有的反曲点,依次计算相邻两个反曲点之间个数据点的曲率值\kappa _{i},并计算相邻两点之间的曲率变化平均值k_{average}作为曲率变化阈值,根据以下方式提取局部曲率极大值点

\left\{\begin{matrix} k_{i}>k_{i-1}&&k_{i}>k_{i+1} \\ k_{i}>k_{average} \end{matrix}\right.

 弓高特征点:利用点距准则获取离散数据点中的弓高特征点,使得得到的主特征点更能体现原始轨迹的几何特征。如图3所示,M_{j},M_{j+1}为提取过反曲点的曲率极值后的两个相邻的主特征点,依次计算相邻两个主特征点之间的其他数据点到线段M_{i}M_{i+1}的最大距离d_{k},设置最大距离d_{max},如果改点d_{k}>d_{max},则点Q_{k}为弓高特征点,并将其作为主特征点,随后在M_{i}Q_{k}Q_{k}M_{i+1}之间递归计算,依次获取M_{i},M_{i+1}之间的所有弓高特征点,并将其作为主要特征点。

图3 弓高特征点示意图

 通过提取反曲点、曲率极值点和弓高误差点,并将这些点作为主要特征点进行拟合即可得到原始曲线大致形同的轨迹,Matlab代码如下:

% 输入参数: data--原始数据点
% 输出参数:T--特征点
%           nummer--特征点在原始数据点中的序号
function [T, nummer] = ExtractFeaturePoints(data)% 记录特征点序号
nummer = [1];
T = zeros(71, 3);
T(1, :) = data(1, :);
% 设置夹角参数误差
thetaMax = pi / 2;
%% 提取反曲点
v = []; k = [];
for i = 2 : length(data) - 2V(i, :) = cross(data(i - 1, :) .* data(i, :), data(i, :) .* data(i + 1, :));V(i+1, :) = cross(data(i, :) .* data(i + 1, :), data(i + 1, :) .* data(i + 2, :));thetaV = acos(cross(V(i, :), acos(V(i + 1, :))) / (norm(V(i, :)) * norm(V(i + 1, :))));if thetaV >= thetaMaxnummer = [nummer, i];
%         temp = i;
%         % 遍历相邻两个反曲点之间的数据点
%         for j = nummer(length(nummer) - 1) + 1 : temp - 1
%             thetaQ = dot((data(j, :) - data(j - 1, :)), data(j + 1, :) - data(j, :)) / (norm(data(j, :) - data(j - 1, :)) * norm(data(j + 1, :) - data(j, :)));
%             k(j) = 2 * sin(thetaQ) / norm(data(j + 1, :) - data(j - 1, :));
%         end
%         for j = nummer(length(nummer) - 1) + 1 : temp - 1   %寻找两个反曲点之间的曲率极值点
%             if k(j) > k(j - 1) && k(j) > k(j + 1)
%                 j
%                T = [T; data(j, :)];
%             end
%         endT(i, :) = data(i, :);   end
end
nummer = [nummer, length(data)];
T(length(data), :) = data(length(data), :);%% 曲率极值点
k = [];                    
for i = 1 : length(nummer) - 1  for j = nummer(i) + 1 : nummer(i + 1) - 1thetaQ = dot((data(j, :) - data(j - 1, :)), data(j + 1, :) - data(j, :)) / (norm(data(j, :) - data(j - 1, :)) * norm(data(j + 1, :) - data(j, :)));k(j) = 2 * sin(thetaQ) / norm(data(j + 1, :) - data(j - 1, :));end
end 
k = [k, 0];
kAverage = mean(k);
for i = 2 : length(k) - 1if k(i) > k(i - 1) && k(i) > k(i + 1) && k(i) > kAverage% 记录主特征点对应的序号,并对序号进行升序排列nummer = sort([nummer, i]);T(i, :) = data(i, :);end
end%% 弓高特征点
dMax = 1.5;
i = 1;
flag = 0;
while i <= length(nummer) - 1j = nummer(i) + 1;rightTemp = nummer(i + 1) - 1;while j < rightTempd = PointToLineDistance(data(j, :), data(nummer(i), :), data(nummer(i + 1), :));j = j + 1; if d > dMaxnummer = sort([nummer, j - 1]);T(j - 1, :) = data(j - 1, :);j = j - 1;flag = 1;breakendendif flag%i = 1;flag = 0;elsei = i + 1;endend

自适应添加拟合误差点

通过主要特征点拟合得到的曲线并不能保证所有数据点都达到精度要求,因此需要通过计算每个数据点与拟合曲线的拟合误差,自适应的将拟合误差最大且超过给定精度的点作为主特征点,重新进行曲线的拟合。

在进行NURBS曲线拟合误差计算之前,首先要计算数据点的节点矢量,本文使用积累弦长参数化方法,得到第i个数据点对应的节点矢值u(i)。

根据两相邻主特征点,采用二分节点矢量法求点到NURBS曲线的最小距离。原始数据点data_i距离特征点M_{i}的距离记为dLeft,对应的节点矢量记为uLeft;原始数据点data_i距离特征点M_{i+1}的距离记为dRight,对应的节点矢量记为uRight。

如果dLeft > dRight,则更新左端点对应的节点参数uLeft = (uLeft+ uRight) / 2;

否则更新右端点对应的节点参数uRight = (uLeft+ uRight) / 2;

 通过上述方式找到距离最近的点对应的节点值uMiddle,通过节点值uMiddle计算对应的NURBS曲线上的点,即可得到数据点data_i距离NURBS曲线的最近距离;通过计算M_{i},M_{i+1}中各数据点与拟合曲线的误差值,从中找出最大误差diatanceMax,如果最近距离distanceMax > dmax(给定的误差上限),则将该点也作为主特征点,重新进行NURBS曲线拟合。遍历所有相邻主特征点之间的原始数据点,找出每段中拟合误差的最大值,并将拟合误差大于误差上限的点添加到主特征点集中,重新进行NURBS拟合,由NURBS曲线的局部支撑性可知,新添加的主特征点不仅可以改善局部的拟合质量,还不会影响其他已经符合要求的区域。

以下为第一段曲线的自适应拟合误差提取代码;

% 输入参数: data--原始数据点
%           points--主要特征点
%           u--特征点的节点矢量
%           dd--控制顶点
% 输出参数:T--特征点
%           nummer--特征点在原始数据点中的序号
function [T, nummer] = DichotomyToFindDistance(points, data, u, U, nummer, dd)T = points;%% 第一段曲线% 以第一段曲线的两端点对应的参数u作为二分区间的左右端点flag = 1;while flagDistance = [];orderNummer = []; for i = nummer(1) + 1 : nummer(2) - 1uLeft = u(nummer(1)); %记录左端点对应的参数u uRight = u(nummer(3)); % 记录右端点对应的参数u% 计算第i个点距离左右端点的距离dLeft = norm(data(i, :) - data(nummer(1), :));dRight = norm(data(i, :) - data(nummer(2), :));% 二分区间法求第i个点距离第一段曲线的距离while uRight - uLeft > 1e-4if dLeft > dRight % 更新区间左端点参数uuLeft = (uLeft+ uRight) / 2;pointLeft = Curve(uLeft, U, 3, 0, dd);dLeft = norm(data(i, :) - pointLeft(1, :));else  % 更新区间右端点参数uuRight = (uLeft+ uRight) / 2;pointRight = Curve(uRight, U, 3, 0, dd);dRight = norm(data(i, :) - pointRight(1, :));endenduMiddle = (uLeft + uRight) / 2;pointMiddle = Curve(uMiddle, U, 3, 0, dd);% 第i个点距离第一段曲线的最近距离distance = sqrt((data(i, 1) - pointMiddle(1))^2 + (data(i, 2) -         pointMiddle(2))^2 + (data(i, 3) - pointMiddle(3))^2);Distance = [Distance, distance]; % 记录第i的点到曲线的最近距离orderNummer = [orderNummer, i]; % 记录Distance中元素对应的序号end% 寻找Distance中最大值,并返回最大值和最大值对应的原数据点中的序号[value, position] = max(Distance);% 如果最大距离大于给定误差,则将改点添加到主特征点中,并记录在原始数据点中的序号% 设定误差为le-2if value > 1e-2flag = 1;nummer = sort([nummer, orderNummer(position)]);points(orderNummer(position), :) = data(orderNummer(position), :);elseflag = 0;endend
end


http://chatgpt.dhexx.cn/article/GHZkQVbc.shtml

相关文章

Nurbs建模

多边形建模和Nurbs建模 Nurbs始终有四个侧面&#xff0c;由有理多项式方程创立的曲线&#xff0c;由控制点定义的曲线。 Nurbs曲线是由一系列多项式构成的&#xff1a;axb0,ax^2bxc0… 能够将任何平面转换为Nurbs NURBS能买构建几乎所有的形状

matlab中Nurbs库的简单使用

文章目录 前言一、简单例子二、复杂一点的NUrbs曲面nrbeval函数 前言 只是为方便学习&#xff0c;不做其他用途&#xff0c;记录matlab中Nurbs的使用&#xff0c;好像记得是添加的matlab中的一个Nurbs库来着。前一段使用&#xff0c;现在不记得了&#xff0c;使用这个程序得先安…

NURBS

非均匀有理样条NURBS( Non-Uniform Rational B-Splines ) 是近年来发展迅速&#xff0c;应用广泛的一种表示曲线曲面造型技术。它能够精确地表示二次规则曲线曲面&#xff0c;从而能用统一的数学形式表示规则曲面与自由曲面&#xff0c;具有可影响曲线曲面形状的权因子&#xf…

【Matlab-NURBS工具箱简要教程及实例 】

Matlab-NURBS工具箱使用教程 添加NURBS工具箱 在附加功能里添加NURBS工具箱 安装完成后可以在’函数’处查看API&#xff0c;也打开文件夹查看。 强烈推荐同步安装gnurbs工具&#xff0c;它完全代替nrbplot展示曲面&#xff0c;且允许用户进行节点拖拽等操作。 NURBS 结…

Nurbs曲线详解

NURBS&#xff08;Non Uniform Rational B-spline&#xff09;曲线通常称为非均匀有理B样条曲线&#xff0c;其数学定义如下&#xff1a; 基函数由递推公式定义&#xff1a; 非均匀&#xff1a;指节点向量的值与间距可以为任意值。这样我们可以在不同区间上得到不同的混合…

NURBS曲面结构及生成原理、修改方法

NURBS全称是Non-Uniform Rational B-Splines中文叫做非均匀有理B样条曲线&#xff0c;Rhinoceros中的模型曲线便是通过NRUBS曲线进行描述&#xff0c;曲面则是通过U和V两个方向的曲线集合来得到&#xff0c;如图&#xff1a; Rhino如何生产曲面原理 由上图我们发现就像织布一样…

MySQL数据库增量备份及恢复方案

MySQL数据库增量备份及恢复方案 u 前言 操作系统崩溃、电源故障、文件系统崩溃和硬件故障等异常状况都可能导致我们正在使用的数据库出现故障而产生数据库中数据不一致的情况。为了保证数据库使用安全&#xff0c;必须定期备份数据库&#xff1b;数据库备份可以分为&#xff1…

差异增量备份和累积增量备份区别(有图)

所谓增量备份&#xff0c;顾名思义即是每次备份仅操作那些发生了"变化"的数据块。RMAN中增量备份有两种&#xff1a;Differential 方式和Cumulative方式。 1、差异增量备份Differential 说起Differential&#xff0c;相当有意思&#xff0c;大家可以这样理解。有一…

数据库的备份与恢复(完全备份,增量备份)

目录 1. 数据库备份的分类1.1 从物理与逻辑的角度&#xff0c;备份可分为1.2 从数据库的备份策略角度&#xff0c;备份可分为 2. 常见的备份方法3. MySQL完全备份与分类3.1 完全备份概述3.2 备份方式3.2.1 物理冷备份及恢复3.2.2 使用专用备份工具 mysqldump3.2.2.1 备份库3.2.…

图解完全备份,增量备份,差异备份

因为网上说的全部都是copy的&#xff0c;所以自己去理解了一下然后整理了一下。 完全备份 完成备份我相信大家都理解&#xff0c;就是一下子备份所有的内容。 增量备份 如上图所示&#xff0c;比如一家公司&#xff0c;周一这家公司进行完全备份&#xff0c;然后周二备份周一…

MySQL 增量备份与恢复

目录 引言一、MySQL 增量备份1. 增量备份特点2. 示例 二、MySQL 增量恢复1. 增量恢复的场景2. 丢失完全备份之后更改的数据的恢复3. 完全备份之后丢失所有数据4. 基于时间点与位置的恢复4.1 基于时间点的恢复4.2 基于位置的恢复 5. 指定企业备份策略的思路 总结 引言 完全备份…

增量备份恢复

** 增量备份恢复案例 **1、配置mysql&#xff0c;设置日志文件 [rootlocalhost bak]# vim /etc/my.cnf 添加&#xff1a; log-binmysql-bin2、重启mysqld服务 systemctl restart mysqld查看日志文件&#xff1a; mysqlbinlog /usr/local/mysql/data/mysql-bin.0000013、创…

mysql实现增量备份

有点要注意 如果你误删了表 想通过这个恢复 必须恢复日志里面有创建表的日志 不然的话是无法回复的 就是必须是从你开始创建表的时候就已经记录日志了 恢复到哪个位置 就按照哪个位置来计算 mysql 5.0不支持增量备份 增量备份定义 mysql数据库会以二进制形式 自动把用户对my…

什么是全量备份,增量备份,差异备份?

背景 今天我司服务器工程大牛看我在备份数据,冷不丁提到了差异备份;但是才疏学浅的我却不知何为差异备份,故而以此为引,开始了对全量备份,增量备份,差异备份这三者的研习;经过一番寻觅,最终找到了他们.呵呵 希望大家有所受益! 问题 1. 什么是全量备份&#xff1f; 2. 什么是增量…

MySQL完全备份和增量备份

MySQL日治管理、数据库备份与恢复 备份的主要目的是灾难恢复&#xff0c;备份还可以测试应用、回滚数据修改、查询历史数据、审计等。而备份、恢复中&#xff0c;日志起到了很重要的作用 一、日志 MySQL的日志默认保存位置为 /usr/local/mysql/data 1.日志类型与作用 ①re…

MySQL 数据库备份(增量备份与恢复)

目录 一、MySQL 增量备份 1.增量备份的概念 1.1 为什么使用增量备份 1.2 增量备份的特点 2.增量备份示例 二、MySQL 增量恢复 1.增量恢复的场景 2.丢失完全备份之后更改的数据的恢复步骤 3.完全备份之后丢失所有数据的恢复步骤 4. 基于时间点与位置的恢复 4.1 基于时间…

mysql数据的备份与恢复

mysql数据的备份与恢复 日志的类型与作用&#xff1a;开启日志方式查看日志是否开启 数据备份的重要性&#xff1a;备份类型&#xff1a;如何选择逻辑备份策略或频率&#xff1f;常见的备份方法&#xff1a;MysQL完全备份优缺点&#xff1a;数据库完全备份分类&#xff1a; 实验…

完全备份 、差异备份、增量备份的区别和特点

数据备份的方式有完全备份、差异备份以及增量备份&#xff0c;那么这三种备份方式有什么区别&#xff0c;在具体应用中又该如何选择呢&#xff1f;本文就这些问题作以介绍。 一、备份方式简介 1、完全备份&#xff08;Full Backup&#xff09; 备份全部选中的文件夹&#xf…

MySQL 数据库备份(二)(增量备份与恢复)

文章目录 一、MySQL 增量备份1.增量备份的概念1.1 为什么使用增量备份1.2 增量备份的特点 2.增量备份示例 二、MySQL 增量恢复1.增量恢复的场景2.丢失完全备份之后更改的数据的恢复步骤3.完全备份之后丢失所有数据的恢复步骤4. 基于时间点与位置的恢复4.1 基于时间点的恢复4.1 …

增量备份

增量备份&#xff0c;是指在完整备份的基础上&#xff0c;每次只是备份自上次备份以来被修改过的数据块。增量备份策略不能用于映像备份&#xff0c;因为映像备份总是对于所有的数据文件。增量备份可以是数据库、数据文件和表空间三个级别。 一、增量备份的种类 第一、累积增…