logo资料库

三次样条曲线插值c#源代码.pdf

第1页 / 共16页
第2页 / 共16页
第3页 / 共16页
第4页 / 共16页
第5页 / 共16页
第6页 / 共16页
第7页 / 共16页
第8页 / 共16页
资料共16页,剩余部分请下载后查看
三次样条曲线插值的基本原理及其 C#实现                三次样条曲线插值的基本原理及其 C#实现    作    者:    simxpert                                                    2018.5.14        I 
三次样条曲线插值的基本原理及其 C#实现    作者简介:  本人长期从事结构强度仿真计算方面的学习和工作,可以为您解决各种结构强度仿真分 析以及专业计算软件定制方面的工作。  扫描二维码可添加本人微信:                          II     
三次样条曲线插值的基本原理及其 C#实现    目        录  1.  简介 .................................................................................................... 1  2.  三次样条插值的基本数学原理 ......................................................... 1  2.1.  插值的问题的提出 .................................................................... 1  2.2.  插值函数的待定系数变量和约束方程 .................................... 2  2.3.  插值函数的最终表达式 ............................................................ 3  2.4.  添加边界条件求解 mi ............................................................... 3  2.5.  根据插值函数进行插值计算 .................................................... 4  3.  三次样条插值函数的 C#实现 ............................................................ 4  4.  SPLine 类的使用方法 ......................................................................... 6  5.  附录 1‐SPLine 类的源代码 ................................................................. 7  6.  附录 2‐Chase 类的源代码 ................................................................ 11    III 
三次样条曲线插值的基本原理及其 C#实现    三次样条曲线插值的数学原理及其 C#实现  作者: simxpert  1. 简介  在工程实践中经常会用到插值,最简单的插值是在相邻的两个样本点之间线 性插值,有时候希望精度高一点,一般都会用三次样条曲线插值。    本文先从理论上讲解三次样条插值的数学原理,然后讲解使用 C#实现三次 样条插值算法的基本过程,最后以实例对算法进行验证。  2. 三次样条插值的基本数学原理  本文并不打算详细讲解完整的三次样条曲线的推导过程,只是梳理一下三次 样条曲线差值的大概的脉络,详细的推导过程可以参考随意一本数值计算教程。  2.1. 插值的问题的提出  在给定的区间[a,b]上有 N 个点,已知其横坐标为:a=x0
三次样条曲线插值的基本原理及其 C#实现    2.2. 插值函数的待定系数变量和约束方程  为了得到精度比较高而且过渡比较平滑的曲线,最常见的就是使用三次样条 插值。如果我们把前面讲的子区间的线性函数提升为 3 次多项式: xaxaxaaxSi )( 3 2 1 2    0  3 (1) 为了保证曲线的连续性和光滑性,必须要对每个区间的插值函数提出一些要求, 这些要求包括: 1).连续性。除了两个边界节点外,任意一个节点 xi 同时属于[xi-1,xi]和[xi,xi+1]这两 个相邻的子区间。我们必须要保证在用这两个区间上的插值函数计算出来的 xi 的 纵坐标值相等,而且要等于已知的 yi 值。即: Si-1(xi)=Si(xi)=yi,i=1,2,…,n-1。 (2) 式(2)包含了 2n-2 个方程,再加两个边界点上 S0(x0)=y0,Sn-1(xn)=yn,共计得到 2n 个方程。 2).一阶导数和二阶导数连续。这个约束条件是为了保证插值函数的曲线足够的 光滑。除了两头的节点外,任意一个中间节点的一阶导数和二阶导数必须连续。 即: xS i ( 1 '  i )  ' ( xS ii ,i=1,2,…,n-1 ) '‘ xS  i i ( 1 )  xS i '’ ( i ,i=1,2,…,n-1 ) (3) (4) 式(3),(4)可以得到 2n-2 个方程。 由于上述约束条件总计可以得到 4n-2 个方程。从(1)式可以看出,每个插值 函数有 4 个未知的待定系数,[a,b]区间内有 n 个子区间,故一共有 4n 个未知待 定系数。未知的变量的数目比约束方程的数目多 2,也就是说我们还缺少两个约 束条件。 缺少的这两个约束条件可以由边界条件来指定。也就是在两个边界点上各施 加一个边界条件。边界条件是是人为指定的,常见的边界条件有 4 种,这个我们   2 
三次样条曲线插值的基本原理及其 C#实现    在后面会提到。 2.3. 插值函数的最终表达式  根据前面的论述,我们只要求出每个子区间的插值函数的 4 个系数 a0, a1, a2,a3 就能完全确定这 n 个插值函数。但是实际中,为了数学推导的方便,我们 并不会直接求出这 4 个变量,而是采取了间接的表达方式来描述每个插值函数。 不同的推导方法,得到的表达形式也各不相同,常见的有三转角法,三弯矩 法,B 样条基函数法等方法。本文并不打算进行详细的推导。因为没必要,任何 一本数值计算的书上都可以找到非常详细的。在这里我直接给出推导结果: yxS i )( i   ( 0 xx i  h i )  y  i  0 1 x  i (  1 h i x )  hm ii  ( 1 xx i  h i )  (5) hm i  i 1  ( 1 x  i  1 h i x ) 其中 x  ,[x i x  i ], xh  i i  1 1  ix , i  1,0 ,..., n  。 1  (x)  (2x  1)(x x )(,1)- 2 1  xx (  2 )1 (6) 式(5)就是插值函数的最终表达式。式(5)看起来比(1)复杂多了,其实仔细看,如 果全部展开,仍然是一个三次多项式。在这个公式中,只有 im 是未知的,其他都 可以根据已知条件直接算出来的。剩下的任务就是如何求出 im 。 我们把(5)所代表的插值函数代入到之前说的约束条件中(2),(3),(4)中,经过 整理,可以得到式(7):  m  ii 1  m 2 i   m  ii 1  g i ,i=1,2,…n-1. (7) 其中  i  h i  hh  i i 1 ,   i -1  i , g i  2.4. 添加边界条件求解 mi  (3  i yy i i 1    i  h  i 1 y  i  1 h i y i 。 ) 前面讲过,我们还需要添加两个边界条件才能求解出位置系数。常见的边界   3 
三次样条曲线插值的基本原理及其 C#实现    条件大概有三、四种。本文不打算涉及所有的边界条件,只选用比较常用的第二 类边界条件(又叫”自然边界条件”):两个边界点的二阶导数为给定的值,其中最 常见给定值为 0,即在两个边界点上有: xS ( 0 '' 0' ) 0 , nxS (''  1n' )  0 (8) 根据式(7),结合边界条件(8),可以推导出求解系数 mi 的矩阵: 2  2             1 2  3  2 2  4  3 2   2    n 2  n 1            m 1 m 2 m 3           m   n  m   n 2 1            =  1g           1   n 2  1 m 0  g 2 g 3   g  n g  n 2 1 (9)            从上面的公式中λ, μ, g 都是可以根据已知条件算出来的,只有 mi 是未知 量。式(9)中的矩阵是一个典型的严格对角占优的对角方程组,可以用追赶法很快 得到解。 2.5. 根据插值函数进行插值计算  在根据 2.4 章中的(9)式求得 mi 之后,代入到 2.3 章中的式(5),即得到所有 的子区间上的插值函数 Si(x)。 对于一个给定的待插值点 xt,我们先要确定 xt 落入到哪个子区间,然后调用 该子区间的插值函数 Si(x)即可求出 xt 对应的插值 yt。 3. 三次样条插值函数的 C#实现  在 C#中实现了三次样条插值函数,实现过程封装在 SPLine 类中。SPLine 类的成员变量为: class SPLine { double[] Xi;//存储已知点的x值 double[] Yi;//存储已知点的y值; double[] A;//存储追赶法矩阵中的A   4 
三次样条曲线插值的基本原理及其 C#实现    double[] B; //存储追赶法矩阵中的B double[] C; //存储追赶法矩阵中的C double[] H;//存储前面公式中的hi double[] Lamda;//存储前面公式中的λi double[] Mu;//存储μi double[] G;//存储gi double[] M;//存储待求的未知量mi int N;//已知点的总数 int n;//n=N-1。 n为区间数,N为点数。 } 成员函数介绍: private void GetH() 功能是求取前文中的h。hi=xi-xi-1。 private void GetLamda_Mu_G() 功能是根据已知条件求出λ, μ, g。计算公式见第3页中间的公式。 private void GetABC() 功能是求出追赶法中的矩阵里面的A,B,C,至于追赶法里面的A,B,C是怎么回 事,这里简单给一个截图: 数组A,B,C分别保存的是上图中的a,b,c。 上图中的待求变量x对应本文中的待求变量m。上图中的d对应本文中的数组G。 private double fai0(double x) private double fai1(double x) 这两个函数对应2.3章中的式(6)中的两个三次多项式。 5  private int GetSection(double x)  
分享到:
收藏