zoukankan      html  css  js  c++  java
  • 样条之Akima光滑插值函数

     核心代码:

      1 //////////////////////////////////////////////////////////////////////
      2 // Akima光滑插值
      3 // t    - 存放指定的插值点的值
      4 // s[]  - 一维数组,长度为5,其中s(0),s(1),s(2),s(3)返回三次多项式的系数,
      5 //        s(4)返回指定插值点t处的函数近似值f(t)(k<0时)或任意值(k>=0时)
      6 // k    - 控制参数,若k>=0,则只计算第k个子区间[x(k), x(k+1)]上的三次多项式的系数
      7 //////////////////////////////////////////////////////////////////////
      8 static float GetValueAkima(const void* valuesPtr, int stride, int n, float t, float* s, int k)
      9 { 
     10     int kk,m,l;
     11     float u[5],p,q;
     12 
     13     // 初值
     14     memset(s, 0, 5*sizeof(float));
     15 
     16     // 特例处理
     17     if (n < 1) 
     18     {
     19         return s[4];
     20     }
     21     if (n == 1) 
     22     { 
     23         s[4] = YfGetFloatValue(valuesPtr, stride, 0);  
     24         s[0] = s[4];
     25         return s[4];
     26     }
     27 
     28     float xStep = 1.0f/(n - 1);
     29 
     30     if (n == 2)
     31     { 
     32         float y0 = YfGetFloatValue(valuesPtr, stride, 0); 
     33         float y1 = YfGetFloatValue(valuesPtr, stride, 1); 
     34         s[0] = y0;
     35         s[1] = (y1-y0)/xStep;
     36         s[4] = y0 + (y1 - y0)*t;
     37         return s[4];
     38     }
     39 
     40     // 插值
     41     if (k<0)
     42     { 
     43         if (t <= xStep) 
     44             kk = 0;
     45         else if (t >= (n-1)*xStep) 
     46             kk = n-2;
     47         else
     48         { 
     49             kk = 1; 
     50             m = n;
     51             while (((kk-m)!=1)&&((kk-m)!=-1))
     52             { 
     53                 l=(kk+m)/2;
     54                 if (t < (l-1)*xStep) 
     55                     m=l;
     56                 else 
     57                     kk=l;
     58             }
     59 
     60             kk=kk-1;
     61         }
     62     }
     63     else 
     64         kk=k;
     65 
     66     if (kk>=n-1) 
     67         kk=n-2;
     68 
     69     u[2]=(YfGetFloatValue(valuesPtr, stride, kk+1) - YfGetFloatValue(valuesPtr, stride, kk))/xStep;
     70     if (n==3)
     71     { 
     72         if (kk==0)
     73         { 
     74             u[3]=(YfGetFloatValue(valuesPtr, stride, 2) - YfGetFloatValue(valuesPtr, stride, 1))/xStep;
     75             u[4]=2.0f*u[3]-u[2];
     76             u[1]=2.0f*u[2]-u[3];
     77             u[0]=2.0f*u[1]-u[2];
     78         }
     79         else
     80         { 
     81             u[1]=(YfGetFloatValue(valuesPtr, stride, 1) - YfGetFloatValue(valuesPtr, stride, 0))/xStep;
     82             u[0]=2.0f*u[1]-u[2];
     83             u[3]=2.0f*u[2]-u[1];
     84             u[4]=2.0f*u[3]-u[2];
     85         }
     86     }
     87     else
     88     { 
     89         if (kk<=1)
     90         { 
     91             u[3]=(YfGetFloatValue(valuesPtr, stride, kk+2) - YfGetFloatValue(valuesPtr, stride, kk+1))/xStep;
     92             if (kk==1)
     93             { 
     94                 u[1]=(YfGetFloatValue(valuesPtr, stride, 1) - YfGetFloatValue(valuesPtr, stride, 0))/xStep;
     95                 u[0]=2.0f*u[1]-u[2];
     96                 if (n==4) 
     97                     u[4]=2.0f*u[3]-u[2];
     98                 else 
     99                     u[4]=(YfGetFloatValue(valuesPtr, stride, 4) - YfGetFloatValue(valuesPtr, stride, 3))/xStep;
    100             }
    101             else
    102             { 
    103                 u[1]=2.0f*u[2]-u[3];
    104                 u[0]=2.0f*u[1]-u[2];
    105                 u[4]=(YfGetFloatValue(valuesPtr, stride, 3) - YfGetFloatValue(valuesPtr, stride, 2))/xStep;
    106             }
    107         }
    108         else if (kk>=(n-3))
    109         { 
    110             u[1]=(YfGetFloatValue(valuesPtr, stride, kk) - YfGetFloatValue(valuesPtr, stride, kk-1))/xStep;
    111             if (kk==(n-3))
    112             { 
    113                 u[3]=(YfGetFloatValue(valuesPtr, stride, n-1) - YfGetFloatValue(valuesPtr, stride, n-2))/xStep;
    114                 u[4]=2.0f*u[3]-u[2];
    115                 if (n==4) 
    116                     u[0]=2.0f*u[1]-u[2];
    117                 else 
    118                     u[0]=(YfGetFloatValue(valuesPtr, stride, kk-1) - YfGetFloatValue(valuesPtr, stride, kk-2))/xStep;
    119             }
    120             else
    121             { 
    122                 u[3]=2.0f*u[2]-u[1];
    123                 u[4]=2.0f*u[3]-u[2];
    124                 u[0]=(YfGetFloatValue(valuesPtr, stride, kk-1) - YfGetFloatValue(valuesPtr, stride, kk-2))/xStep;
    125             }
    126         }
    127         else
    128         { 
    129             u[1]=(YfGetFloatValue(valuesPtr, stride, kk  ) - YfGetFloatValue(valuesPtr, stride, kk-1))/xStep;
    130             u[0]=(YfGetFloatValue(valuesPtr, stride, kk-1) - YfGetFloatValue(valuesPtr, stride, kk-2))/xStep;
    131             u[3]=(YfGetFloatValue(valuesPtr, stride, kk+2) - YfGetFloatValue(valuesPtr, stride, kk+1))/xStep;
    132             u[4]=(YfGetFloatValue(valuesPtr, stride, kk+3) - YfGetFloatValue(valuesPtr, stride, kk+2))/xStep;
    133         }
    134     }
    135 
    136     s[0] = fabs(u[3]-u[2]);
    137     s[1] = fabs(u[0]-u[1]);
    138     if ((s[0]+1.0f == 1.0f) && (s[1]+1.0f == 1.0f))
    139         p = (u[1]+u[2])/2.0f;
    140     else 
    141         p = (s[0]*u[1]+s[1]*u[2])/(s[0]+s[1]);
    142 
    143     s[0] = fabs(u[3]-u[4]);
    144     s[1] = fabs(u[2]-u[1]);
    145     if ((s[0]+1.0f==1.0f) && (s[1]+1.0f==1.0f))
    146         q = (u[2]+u[3])/2.0f;
    147     else 
    148         q = (s[0]*u[2]+s[1]*u[3])/(s[0]+s[1]);
    149 
    150     s[0] = YfGetFloatValue(valuesPtr, stride, kk);
    151     s[1] = p;
    152     s[3] = xStep;
    153     s[2] = (3.0f*u[2]-2.0f*p-q)/s[3];
    154     s[3] = (q+p-2.0f*u[2])/(s[3]*s[3]);
    155 
    156     //if (k<0)
    157     { 
    158         p=t-(kk*xStep);
    159         s[4]=s[0]+s[1]*p+s[2]*p*p+s[3]*p*p*p;
    160     }
    161 
    162     return s[4];
    163 
    164 }

    切图:

     、 

     

    相关软件的下载地址为:http://files.cnblogs.com/WhyEngine/TestSpline.zip

  • 相关阅读:
    A20 烧录和启动 log
    图像处理---图像分割技术---基于图像灰度分布的阈值方法一
    H.265---内容总览
    H.265---仿射运动模型和双线性运动模型
    H.265---帧内预测与帧间预测
    linux内核---进程通信---消息队列
    linux内核---嵌入式linux内核的五个子系统
    高并发服务器---nginx---实现负载均衡的几种方式
    高并发服务器---nginx---正向代理和反向代理
    【CV系列】基于形态学梯度的边缘检测
  • 原文地址:https://www.cnblogs.com/WhyEngine/p/4020429.html
Copyright © 2011-2022 走看看