Advertisement
agmike

CubicSpline.Interpolate()

Apr 9th, 2014
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.64 KB | None | 0 0
  1.         public override void Interpolate()
  2.         {
  3.             base.Interpolate();
  4.             if (Points.Count == 0)
  5.                 return;
  6.             if (SegmentCount < 1)
  7.                 a = b = c = d = null;
  8.             else {
  9.                 if (a == null || a.Count() != SegmentCount) {
  10.                     my = new float[SegmentCount - 1];
  11.                     mc = new float[SegmentCount - 1];
  12.                     mr = new float[Math.Max(0, SegmentCount - 2)];
  13.                     a = new float[SegmentCount];
  14.                     b = new float[SegmentCount];
  15.                     c = new float[SegmentCount];
  16.                     d = new float[SegmentCount];
  17.                 }
  18.  
  19.                 float leftDeriv;
  20.                 bool leftNatural = !GetProperty("LeftDerivative", out leftDeriv);
  21.                 float rightDeriv;
  22.                 bool rightNatural = !GetProperty("RightDerivative", out rightDeriv);
  23.  
  24.                 for (int i = 0; i < SegmentCount; ++i)
  25.                     d[i] = Points[i].Y;
  26.  
  27.                 for (int i = 1; i < SegmentCount; ++i) {
  28.                     mc[i - 1] = 2f * (Points[i + 1].X - Points[i - 1].X);
  29.  
  30.                     my[i - 1] = 3f * ((Points[i + 1].Y - Points[i].Y) / (Points[i + 1].X - Points[i].X) -
  31.                                   (Points[i].Y - Points[i - 1].Y) / (Points[i].X - Points[i - 1].X));
  32.  
  33.                     if (i < SegmentCount - 1)
  34.                         mr[i - 1] = Points[i + 1].X - Points[i].X;
  35.                 }
  36.  
  37.                 for (int i = 1; i < SegmentCount - 1; ++i) {
  38.                     float k = mr[i - 1] / mc[i - 1];
  39.                     mc[i] = mc[i] - mr[i - 1] * k;
  40.                     my[i] = my[i] - my[i - 1] * k;
  41.                 }
  42.  
  43.                 if (SegmentCount > 1) {
  44.                     b[SegmentCount - 1] = my[SegmentCount - 2] / mc[SegmentCount - 2];
  45.  
  46.                     for (int i = SegmentCount - 2; i >= 1; --i)
  47.                         b[i] = (my[i - 1] - b[i + 1] * mr[i - 1]) / mc[i - 1];
  48.                 }
  49.  
  50.                 b[0] = 0f;
  51.  
  52.                 for (int i = 0; i < SegmentCount - 1; ++i)
  53.                     a[i] = 1f / (3f * (Points[i + 1].X - Points[i].X)) * (b[i + 1] - b[i]);
  54.                 a[SegmentCount - 1] = -1f / (3f * (Points[SegmentCount].X - Points[SegmentCount - 1].X)) * b[SegmentCount - 1];
  55.  
  56.                 for (int i = 0; i < SegmentCount - 1; ++i)
  57.                 {
  58.                     float h = Points[i + 1].X - Points[i].X;
  59.                     c[i] = (Points[i + 1].Y - Points[i].Y) / h - h / 3f * (b[i + 1] + 2f * b[i]);
  60.                 }
  61.                 {
  62.                     float h = Points[SegmentCount].X - Points[SegmentCount - 1].X;
  63.                     c[SegmentCount - 1] = (Points[SegmentCount].Y - Points[SegmentCount - 1].Y) / h - h / 3f * (2f * b[SegmentCount - 1]);
  64.                 }
  65.             }
  66.         }
  67.  
  68.         public override float GetValue(float x)
  69.         {
  70.             if (SegmentCount < 1)
  71.                 return Points[0].Y;
  72.  
  73.             int s = FindSegment(x);
  74.             if (x <= Points[0].X) {
  75.                 float xr = x - Points[0].X;
  76.                 return c[0] * xr + d[0];
  77.             }
  78.             else if (x >= Points[PointsCount - 1].X) {
  79.                 s = SegmentCount - 1;
  80.                 float xr = x - Points[SegmentCount].X;
  81.                 float h = Points[SegmentCount].X - Points[s].X;
  82.                 return ((3f * a[s] * h + 2f * b[s]) * h + c[s]) * xr + Points[SegmentCount].Y;
  83.             }
  84.             else {
  85.                 float xr = x - Points[s].X;
  86.                 return ((a[s] * xr + b[s]) * xr + c[s]) * xr + d[s];
  87.             }
  88.         }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement