void set_cubic_poly2(PolyS p, double p1x, double p1y,
                             double p2x, double p2y, double dd1,
                             double dd2)
        {
            /*
             * a=(dd1-dd2)/(6*x1-6*x2);
             * b=(dd2*x1-dd1*x2)/(2*x1-2*x2);
             * c=(-6*y2+6*y1+(dd2+2*dd1)*x2^2+(2*dd1-2*dd2)*x1*x2+(-2*dd2-dd1)*x1^2)/(6*x1-6*x2);
             * d=-(x1*((dd2+2*dd1)*x2^2-6*y2)+6*x2*y1+(-2*dd2-dd1)*x1^2*x2)/(6*x1-6*x2);
             */

            // FIXME simplify

            p.a = (dd1 - dd2) / (6.0 * p1x - 6.0 * p2x);

            p.b = (dd2 * p1x - dd1 * p2x) / (2.0 * p1x - 2.0 * p2x);

            p.c = (6.0 * p1y - 6.0 * p2y + (dd2 + 2.0 * dd1) * p2x * p2x
                   + (2.0 * dd1 - 2.0 * dd2) * p1x * p2x - (2.0 * dd2 + dd1) * p1x * p1x)
                  / (6.0 * p1x - 6.0 * p2x);

            p.d = -(p1x * ((dd2 + 2.0 * dd1) * p2x * p2x - 6.0 * p2y) + 6.0 * p2x * p1y
                    - (2.0 * dd2 + dd1) * p1x * p1x * p2x)
                  / (6.0 * p1x - 6.0 * p2x);
        }
 void set_quadratic_poly(PolyS p, double px, double py,
                         double d, double dd)
 {
     p.a = 0;
     p.b = dd / 2.0;
     p.c = -px * dd + d;
     p.d = 0.5 * px * px * dd - px * d + py;
 }
 void set_linear_poly(PolyS p, double p1x, double p1y,
                      double d1)
 {
     p.a = 0.0;
     p.b = 0.0;
     p.c = d1;
     p.d = p1y - d1 * p1x;
 }
 void set_linear_poly(PolyS p, double p1x, double p1y,
                      double p2x, double p2y)
 {
     p.a = 0.0;
     p.b = 0.0;
     p.c = (p1y - p2y) / (p1x - p2x);
     p.d = (p2x * p1y - p1x * p2y) / (p2x - p1x);
 }
        double interpolate_quadratic(int d, double x)
        {
            PolyS p = _poly[_data_set.get_nearest(x)];

            switch (d)
            {
            case (0):
                return(x * (p.b * x + p.c) + p.d);

            case (1):
                return(2.0 * p.b * x + p.c);

            case (2):
                return(2.0 * p.b);

            default:
                return(0.0);
            }
        }
        void set_quadratic_poly(PolyS p, double p1x, double p1y,
                                double p2x, double p2y, double p3x,
                                double p3y)
        {
            double n = ((p2x - p1x) * (p3x - p1x) * (p3x - p2x));

            p.a = 0.0;

            p.b = (p3y * (p2x - p1x) + p2y * (p1x - p3x) + p1y * (p3x - p2x)) / n;

            double p1x2 = MathUtils.square(p1x);
            double p2x2 = MathUtils.square(p2x);
            double p3x2 = MathUtils.square(p3x);

            p.c = (p3y * (p1x2 - p2x2) + p2y * (p3x2 - p1x2) + p1y * (p2x2 - p3x2)) / n;

            p.d = (p3y * (p1x * p2x2 - p2x * p1x2) + p2y * (p3x * p1x2 - p1x * p3x2)
                   + p1y * (p2x * p3x2 - p3x * p2x2))
                  / n;
        }
        double interpolate_cubic(int d, double x)
        {
            PolyS p = _poly[_data_set.get_interval(x)];

            switch (d)
            {
            case (0):
                return(((p.a * x + p.b) * x + p.c) * x + p.d);

            case (1):
                return((3.0 * p.a * x + 2.0 * p.b) * x + p.c);

            case (2):
                return(6.0 * p.a * x + 2.0 * p.b);

            case (3):
                return(6.0 * p.a);

            default:
                return(0.0);
            }
        }
        void set_cubic_poly(PolyS p, double p1x, double p1y,
                            double p2x, double p2y, double d1, double d2)
        {
            /*
             * a=-(-2*y2+2*y1+(d2+d1)*x2+(-d2-d1)*x1)/(-x2^3+3*x1*x2^2-3*x1^2*x2+x1^3),
             * b=(-3*x2*y2+x1*((d2-d1)*x2-3*y2)+(3*x2+3*x1)*y1+(d2+2*d1)*x2^2+(-2*d2-d1)*x1^2)/(-x2^3+3*x1*x2^2-3*x1^2*x2+x1^3),
             * c=-(x1*((2*d2+d1)*x2^2-6*x2*y2)+6*x1*x2*y1+d1*x2^3+(-d2-2*d1)*x1^2*x2-d2*x1^3)/(-x2^3+3*x1*x2^2-3*x1^2*x2+x1^3),
             * d=(x1^2*((d2-d1)*x2^2-3*x2*y2)+x1^3*(y2-d2*x2)+(3*x1*x2^2-x2^3)*y1+d1*x1*x2^3)/(-x2^3+3*x1*x2^2-3*x1^2*x2+x1^3)
             */
            double x1 = p1x;
            double x2 = p2x;
            double y1 = p1y;
            double y2 = p2y;

            // FIXME simplify

            p.a = -(2.0 * y1 - 2.0 * y2 + (d2 + d1) * x2 - (d2 + d1) * x1)
                  / (3.0 * x1 * x2 * x2 - x2 * x2 * x2 - 3.0 * x1 * x1 * x2
                     + x1 * x1 * x1);

            p.b = (x1 * ((d2 - d1) * x2 - 3.0 * y2) - 3.0 * x2 * y2
                   + (3.0 * x2 + 3.0 * x1) * y1 + (d2 + 2.0 * d1) * x2 * x2
                   - (2.0 * d2 + d1) * x1 * x1)
                  / (3.0 * x1 * x2 * x2 - x2 * x2 * x2 - 3.0 * x1 * x1 * x2
                     + x1 * x1 * x1);

            p.c = -(x1 * ((2.0 * d2 + d1) * x2 * x2 - 6.0 * x2 * y2) + 6.0 * x1 * x2 * y1
                    + d1 * x2 * x2 * x2 -
                    (d2 + 2.0 * d1) * x1 * x1 * x2
                    - d2 * x1 * x1 * x1)
                  / (3.0 * x1 * x2 * x2 - x2 * x2 * x2 - 3.0 * x1 * x1 * x2
                     + x1 * x1 * x1);

            p.d = (x1 * x1 * ((d2 - d1) * x2 * x2 - 3.0 * x2 * y2)
                   + x1 * x1 * x1 * (y2 - d2 * x2)
                   + (3.0 * x1 * x2 * x2 - x2 * x2 * x2) * y1 + d1 * x1 * x2 * x2 * x2)
                  / (3.0 * x1 * x2 * x2 - x2 * x2 * x2 - 3.0 * x1 * x1 * x2
                     + x1 * x1 * x1);
        }