C-5 B样条曲线

embedded/2024/12/28 7:08:08/

C-5 B样条曲线

N i , 0 ( u ) = { 1 , u i ≤ u < u i + 1 0 , o t h e r s N_{i,0}(u)=\left\{\begin{matrix} 1 , \quad u_i\le u <u_{i+1} \\0 ,\quad others \qquad \quad\end{matrix}\right. Ni,0(u)={1,uiu<ui+10,others

N i , p ( u ) = u − u i u i + p − u i ⋅ N i , p − 1 ( u ) + u i + p + 1 − u u i + p + 1 − u i + 1 ⋅ N i + 1 , p − 1 ( u ) N_{i,p}(u)=\frac{u -u_i}{u_{i+p}-u_i} \cdot N_{i,p-1}(u) +\frac{u_{i+p+1} -u}{u_{i+p+1}-u_{i+1}} \cdot N_{i+1,p-1}(u) Ni,p(u)=ui+puiuuiNi,p1(u)+ui+p+1ui+1ui+p+1uNi+1,p1(u)

C ( u ) = ∑ i = 1 n N i , p ( u ) ⋅ C o n t r o l P o i n t ( i ) C(u) = \sum ^n_{i=1} N_{i,p}(u)\cdot ControlPoint_{(i)} C(u)=i=1nNi,p(u)ControlPoint(i)

  • C就是我们要求的曲线

  • 只需要给定控制点数组和节点向量数组,我们就能根据以上公式得到一条B样条曲线

  • n是给定控制点数组的长度,p是B样条的阶数,一般就直接设置为3了, u i u_i ui就算节点向量数组,可以从公式中发现,节点向量的长度等于 控制点数组长度+阶数+1。(从递归公式中的 u i + p + 1 u_{i+p+1} ui+p+1可以看出来)

  • 前面的参数 N i , p N_{i,p} Ni,p,只需要给定节点向量和阶数就能直接提前求出来,可以写成矩阵的形式。方便后面移动控制点求解。

  • Step标准中,B样条是如下定义的:

    • 
      #21=B_SPLINE_CURVE_WITH_KNOTS('',3,(#118,#119,#120,#121),.UNSPECIFIED.,.F.,.F.,(4,4),(0.,1.),.UNSPECIFIED.);//相当于输入控制点 (#118,#119,#120,#121),和节点向量(0,0,0,0,1,1,1,1)//有一个重复的节点,那里的连续性就会减一,具体可以见Games102,刘利刚老师的课//3指3阶B样条曲线,第一个F指这个曲线没有闭合,(4,4)是修饰后面的节点向量,这条曲线比较简单,一般是下面#31这样的//1阶B样条曲线的连续性是C1,也就是连连上,导数不连续。而3阶B样条曲线的连续性是C3#31=B_SPLINE_CURVE_WITH_KNOTS('',3,(#88,#89,#90,#91,#92,#93,#94),.UNSPECIFIED.,.T.,.F.,(4,1,1,1,4),(0.,0.190110440975709,0.596109450554148,
      0.871779783977488,1.),.UNSPECIFIED.);
      

局部性

  • 局部性:我们操控第i个控制点,只能控制有限的一段曲线而不是影响到这条曲线
  • 我们发现,控制点i前面的参数是 N i , p N_{i,p} Ni,p.这个参数一递归,最多最多只能影响到 u i u_i ui u i + p + 1 u_{i+p+1} ui+p+1这P+2个节点范围内的曲线,因为递归公式中参数的范围就是这个,然后在用阶梯函数吧,一点点线性插值,构成这一段B样条曲线

代码

  • 对于上述的#21的样条曲线,可以用如下代码求解,并将其离散化成32个点
  • 代码和详细注释如下,代码中的t相当于公式中的u,一般是从0到1的参变量
#include <iostream>
#include <vector>
#include <array> class Point {
public:double x=0;double y=0;
};
class NubrsEdge {
public:bool ISClOSED=0;//B样条曲线的介数,一般为3int P;//控制点std::vector<Point> ControlPoints;//节点向量std::vector<double> u;//利用节点向量计算得到的参数,我们把B样条曲线统一分成32份std::vector<std::array<double, 32>> N_p;//递归计算参数Ndouble N(int i,int p,double t) {if (p == 0) {if (u[i] <= t && t < u[i + 1]) return 1;else return 0;}else{double x1 = 0;//对重复节点的处理!!!!!!!!!!//不然就出现除数等于0的情况了if (u[i + p] != u[i]) x1 = (t - u[i]) / (u[i + p] - u[i]);double x2 = 0;//对重复节点的处理if(u[i + p + 1] != u[i + 1])x2 = (u[i + p + 1] - t) / (u[i + p + 1] - u[i + 1]);return x1 * N(i, p - 1, t) + x2 * N(i + 1, p - 1, t);}}//计算参数,$N_{i,p}(u)$void calculate_N_p() {N_p.resize(ControlPoints.size());for (int i = 0; i < ControlPoints.size(); i++) {for (int t = 0; t < 32; t++) {N_p[i][t] = N(i, P, double(t)/31.00001);}}}//相当于在做矩阵的乘法std::vector<Point> Discretization() {calculate_N_p();std::vector<Point> result(32);for (int t = 0; t < 32; t++) {for(int i=0;i < ControlPoints.size(); i++){result[t].x += ControlPoints[i].x * N_p[i][t];result[t].y += ControlPoints[i].y * N_p[i][t];}}return result;}
};
int main()
{NubrsEdge e;// u.size() = 8 = ControlPoints.size + P +1 =4 + 3 + 1e.ControlPoints= {{-410.738133667533,-34.3141639975569},{-360.696916167804,124.126883382823},{-317.136530803152,125.95962808178},{-280.056977573576,-28.8159299006879}};e.u = { 0, 0, 0, 0, 1,1,1, 1 };e.P = 3;// 离散化曲线std::vector<Point> curvePoints = e.Discretization();// 打印结果for (int i = 0; i < curvePoints.size(); i++) {std::cout << "Point " << i << ": (" << curvePoints[i].x << ", " << curvePoints[i].y << ")" << std::endl;}return 0;
}
  • 可以发现起始点和结束点与第一个和最后一个控制点重合

在这里插入图片描述


http://www.ppmy.cn/embedded/148934.html

相关文章

机器学习之PCA降维

主成分分析&#xff08;PCA&#xff0c;Principal Component Analysis&#xff09; 主成分分析&#xff08;PCA&#xff09;是一种常见的无监督学习技术&#xff0c;广泛应用于数据降维、数据可视化以及特征提取等任务。PCA的目标是通过线性变换将数据从高维空间映射到低维空间…

postgresql ERROR: cannot drop the currently open database

postgresql ERROR: cannot drop the currently open database 解释&#xff1a; 这个错误表明你正在尝试删除或者切换当前正在使用的数据库。在PostgreSQL中&#xff0c;一个数据库对应着一个进程&#xff0c;当一个数据库处于打开状态时&#xff0c;你不能直接删除或者切换它…

[ThinkPHP]5.0.23-Rce 1

[ThinkPHP]5.0.23-Rce 1 根据题目知道这是一个5.0.23的PHP RCE&#xff0c;话不多说直接上扫描器 检测出Payload url地址&#xff1a; ?scaptcha&test-1 Post表单参数: _method__construct&filter[]phpinfo&methodget&server[REQUEST_METHOD]1HackBar构造p…

软考高项,项目整合管理

定义 项目整合管理包括识别、定义、组合、统一和协调项目管理过程组的各个过程和项目管理活动。在项目管理中&#xff0c;整合管理兼具统一、合并、沟通和建立联系的性质&#xff0c;项目整合管理贯穿项目始终。项目整合管理的目标包括&#xff1a;①资源分配&#xff1b;②平衡…

Yolo11改策略:卷积改进|SAC,提升模型对小目标和遮挡目标的检测性能|即插即用

摘要 一、论文介绍 本文参考的论文主要介绍了DetectoRS模型&#xff0c;一个高性能的目标检测模型。DetectoRS通过引入递归特征金字塔&#xff08;RFP&#xff09;和可切换空洞卷积&#xff08;SAC&#xff09;两大创新点&#xff0c;显著提升了目标检测的精度。尽管原文并未…

PCL点云库入门——PCL库点云滤波算法之直通滤波(PassThrough)和条件滤波(ConditionalRemoval)

0、滤波算法概述 PCL点云库中的滤波算法是处理点云数据不可或缺的一部分&#xff0c;它们能够有效地去除噪声、提取特征或进行数据降维。例如&#xff0c;使用体素网格滤波&#xff08;VoxelGrid&#xff09;可以减少点云数据量&#xff0c;同时保留重要的形状特征。此外&#…

计算机图形学知识点汇总

一、计算机图形学定义与内容 1.图形 图形分为“图”和“形”两部分。 其中&#xff0c;“形”指形体或形状&#xff0c;存在于客观世界和虚拟世界&#xff0c;它的本质是“表示”&#xff1b;而图则是包含几何信息与属性信息的点、线等基本图元构成的画面&#xff0c;用于表达…

List反转的方法

1.list循环 List<String> strsnew ArrayList<>();for (int i 0; i <100 ; i) {strs.add("a"i);}List<String> fzstrsnew ArrayList<>();for (int i strs.size()-1; i >0 ; i--) {fzstrs.add(strs.get(i));}System.out.println(fzstr…