Advertisement
agmike

Splines

Aug 18th, 2011
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.76 KB | None | 0 0
  1. /* LSE_FILE_HEADER */
  2. /* LSE_LLIB_HEADER */
  3.  
  4. include "lse.llib.util.gs"
  5.  
  6.  
  7. class LlSpline
  8. {
  9.     public float XK = 1.0, XS = 0.0;
  10.     public float YK = 1.0, YS = 0.0;
  11.  
  12.     public void Init(float[] x, float[] y) {}
  13.  
  14.     public float Y(float x) { return 0.0; }
  15.     public float DYDX(float x) { return 0.0; }
  16. };
  17.  
  18.  
  19. class LlLinearSpline isclass LlSpline
  20. {
  21.     float[] sx, sy;
  22.     int count;
  23.  
  24.     public void Init(float[] x, float[] y)
  25.     {
  26.         LlUtil.Assert(x.size() == y.size() and x.size() >= 2);
  27.         sx = x;
  28.         sy = y;
  29.         count = x.size() - 1;
  30.     }
  31.  
  32.     final float linearFunc(float x0, float x1, float y0, float y1, float x)
  33.     {
  34.         if (x0 == x1)
  35.             return y0;
  36.         float k = (y1 - y0) / (x1 - x0);
  37.         float b = y1 - k * x1;
  38.         return k * x + b;
  39.     }
  40.  
  41.     final int findSegment(float x)
  42.     {
  43.         if (x <= sx[0])
  44.             return 0;
  45.         else if (x >= sx[count])
  46.             return count - 1;
  47.  
  48.         int l = 0;
  49.         int r = count;
  50.         while (l < r - 1)
  51.         {
  52.             int m = (l + r) / 2;
  53.             if (x <= sx[m])
  54.                 r = m;
  55.             else
  56.                 l = m;
  57.         }
  58.         return l;
  59.     }
  60.  
  61.     public float Y(float x)
  62.     {
  63.         x = x * XK + XS;
  64.         int l = findSegment(x);
  65.         return linearFunc(sx[l], sx[l + 1], sy[l], sy[l + 1], x) * YK + YS;
  66.     }
  67.  
  68.     final float linearFuncDeriv(float x0, float x1, float y0, float y1, float x)
  69.     {
  70.         if (x0 == x1)
  71.             return y0;
  72.         float k = (y1 - y0) / (x1 - x0);
  73.         return k;
  74.     }
  75.  
  76.     public float DYDX(float x)
  77.     {
  78.         x = x * XK + XS;
  79.         int l = findSegment(x);
  80.         return linearFuncDeriv(sx[l], sx[l + 1], sy[l], sy[l + 1], x) * YK * XK;
  81.     }
  82. };
  83.  
  84.  
  85. class LlCubicSpline isclass LlSpline
  86. {
  87.     float[] px;
  88.     float[] py;
  89.     int scount;
  90.     float[] sa;
  91.     float[] sb;
  92.     float[] sc;
  93.     float[] sd;
  94.  
  95.     void interpolate()
  96.     {
  97.         float[] mr = new float[scount - 2];
  98.         float[] mc = new float[scount - 1];
  99.         float[] my = new float[scount - 1];
  100.  
  101.         float[] h = new float[scount];
  102.         float[] e = new float[scount];
  103.  
  104.         sa = new float[scount];
  105.         sb = new float[scount];
  106.         sc = new float[scount + 1];
  107.         sd = py;
  108.  
  109.         int i;
  110.         for (i = 0; i < scount; ++i)
  111.         {
  112.             h[i] = px[i + 1] - px[i];
  113.             e[i] = (py[i + 1] - py[i]) / h[i];
  114.         }
  115.  
  116.         for (i = 1; i < scount; ++i)
  117.         {
  118.             int j = i - 1;
  119.             mc[j] = 2.0 * (h[i - 1] + h[i]);
  120.  
  121.             my[j] = 3.0 * (e[i] - e[i - 1]);
  122.  
  123.             if (i < scount - 1)
  124.                 mr[j] = h[i];
  125.         }
  126.  
  127.         for (i = 1; i < scount - 1; ++i)
  128.         {
  129.             int j = i - 1;
  130.             float k = mr[j] / mc[j];
  131.             mc[j + 1] = mc[j + 1] - mr[j] * k;
  132.             my[j + 1] = my[j + 1] - my[j] * k;
  133.         }
  134.  
  135.         if (scount > 1)
  136.         {
  137.             int k = scount - 1;
  138.             int j = k - 1;
  139.             sb[k] = my[j] / mc[j];
  140.  
  141.             for (i = scount - 2; i >= 1; --i)
  142.             {
  143.                 j = i - 1;
  144.                 sb[i] = (my[j] - sb[i + 1] * mr[j]) / mc[j];
  145.             }
  146.         }
  147.  
  148.         sb[0] = 0.0;
  149.  
  150.         for (i = 0; i < scount - 1; ++i)
  151.         {
  152.             sa[i] = (sb[i + 1] - sb[i]) / (3.0 * h[i]);
  153.             sc[i] = e[i] - h[i] / 3.0 * (sb[i + 1] + 2.0 * sb[i]);
  154.         }
  155.  
  156.         int k = scount - 1;
  157.         sa[k] = -sb[k] / (3.0 * h[k]);
  158.         sc[k] = e[k] - h[k] / 3.0 * (2.0 * sb[k]);
  159.         sc[scount] = (3.0 * sa[k] * h[k] + 2.0 * sb[k]) * h[k] + sc[k];
  160.     }
  161.  
  162.     public void Init(float[] x, float[] y)
  163.     {
  164.         LlUtil.Assert(x.size() == y.size() and x.size() >= 2);
  165.         px = x;
  166.         py = y;
  167.         scount = x.size() - 1;
  168.         interpolate();
  169.     }
  170.  
  171.     public float Y(float x)
  172.     {
  173.         x = x * XK + XS;
  174.         float y = 0.0;
  175.         if (x <= px[0])
  176.         {
  177.             float xr = x - px[0];
  178.             y = sc[0] * xr + sd[0];
  179.         }
  180.         else if (x >= px[scount])
  181.         {
  182.             float xr = x - px[scount];
  183.             y = sc[scount] * xr + sd[scount];
  184.         }
  185.         else
  186.         {
  187.             int l = 0;
  188.             int r = scount;
  189.             while (l < r - 1)
  190.             {
  191.                 int m = (l + r) / 2;
  192.                 if (x <= px[m])
  193.                     r = m;
  194.                 else
  195.                     l = m;
  196.             }
  197.             float xr = x - px[l];
  198.             y = ((sa[l] * xr + sb[l]) * xr + sc[l]) * xr + sd[l];
  199.         }
  200.  
  201.         return y * YK + YS;
  202.     }
  203.  
  204.     public float DYDX(float x)
  205.     {
  206.         x = x * XK + XS;
  207.         float y = 0.0;
  208.         if (x <= px[0])
  209.         {
  210.             y = sc[0];
  211.         }
  212.         else if (x >= px[scount])
  213.         {
  214.             y = sc[scount];
  215.         }
  216.         else
  217.         {
  218.             int l = 0;
  219.             int r = scount;
  220.             while (l < r - 1)
  221.             {
  222.                 int m = (l + r) / 2;
  223.                 if (x <= px[m])
  224.                     r = m;
  225.                 else
  226.                     l = m;
  227.             }
  228.             float xr = x - px[l];
  229.             y = (3.0 * sa[l] * xr + 2.0 * sb[l]) * xr + sc[l];
  230.         }
  231.  
  232.         return y * YK * XK;
  233.     }
  234. };
  235.  
  236.  
  237. class LlSplineConstructorBase
  238. {
  239.     public LlLinearSpline NewLinearSpline(float[] x, float[] y)
  240.     {
  241.         LlLinearSpline ret = new LlLinearSpline();
  242.         ret.Init(x, y);
  243.         return ret;
  244.     }
  245.  
  246.     public LlCubicSpline NewCubicSpline(float[] x, float[] y)
  247.     {
  248.         LlCubicSpline ret = new LlCubicSpline();
  249.         ret.Init(x, y);
  250.         return ret;
  251.     }
  252. };
  253.  
  254.  
  255. static class LlSplineConstructor isclass LlSplineConstructorBase
  256. {
  257. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement