// Cubic Spline interpolation: http://www.codeproject.com/Articles/560163/Csharp-Cubic-Spline-Interpolation
        private IList <Point> ComputeSplineSeries(IPointSeries inputPointSeries, bool isSplineEnabled, int upsampleBy)
        {
            IList <Point> result = null;

            if (!isSplineEnabled)
            {
                // No spline, just return points. Note: for large datasets, even the copy here causes performance problems!
                result = new List <Point>(inputPointSeries.Count);
                for (int i = 0; i < inputPointSeries.Count; i++)
                {
                    result.Add(new Point(inputPointSeries.XValues[i], inputPointSeries.YValues[i]));
                }
                return(result);
            }

            // Spline enabled
            int n = inputPointSeries.Count * upsampleBy;
            var x = inputPointSeries.XValues.ToArray();
            var y = inputPointSeries.YValues.ToArray();

            double[] xs       = new double[n];
            double   stepSize = (x[x.Length - 1] - x[0]) / (n - 1);

            for (int i = 0; i < n; i++)
            {
                xs[i] = x[0] + i * stepSize;
            }

            var cubicSpline = new CubicSpline();

            double[] ys = cubicSpline.FitAndEval(x, y, xs);

            result = new List <Point>(n);
            for (int i = 0; i < xs.Length; i++)
            {
                result.Add(new Point(xs[i], ys[i]));
            }
            return(result);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Fit the input x,y points using a 'geometric' strategy so that y does not have to be a single-valued
        /// function of x.
        /// </summary>
        /// <param name="x">Input x coordinates.</param>
        /// <param name="y">Input y coordinates, do not need to be a single-valued function of x.</param>
        /// <param name="nOutputPoints">How many output points to create.</param>
        /// <param name="xs">Output (interpolated) x values.</param>
        /// <param name="ys">Output (interpolated) y values.</param>
        public static void FitGeometric(double[] x, double[] y, int nOutputPoints, out double[] xs, out double[] ys)
        {
            // Compute distances
            int n = x.Length;

            double[] dists = new double[n]; // cumulative distance
            dists[0] = 0;
            double totalDist = 0;

            for (int i = 1; i < n; i++)
            {
                double dx   = x[i] - x[i - 1];
                double dy   = y[i] - y[i - 1];
                double dist = (double)Math.Sqrt(dx * dx + dy * dy);
                totalDist += dist;
                dists[i]   = totalDist;
            }

            // Create 'times' to interpolate to
            double dt = totalDist / (nOutputPoints - 1);

            double[] times = new double[nOutputPoints];
            times[0] = 0;

            for (int i = 1; i < nOutputPoints; i++)
            {
                times[i] = times[i - 1] + dt;
            }

            // Spline fit both x and y to times
            CubicSpline xSpline = new CubicSpline();

            xs = xSpline.FitAndEval(dists, x, times);

            CubicSpline ySpline = new CubicSpline();

            ys = ySpline.FitAndEval(dists, y, times);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Static all-in-one method to fit the splines and evaluate at X coordinates.
        /// </summary>
        /// <param name="x">Input. X coordinates to fit.</param>
        /// <param name="y">Input. Y coordinates to fit.</param>
        /// <param name="xs">Input. X coordinates to evaluate the fitted curve at.</param>
        /// <param name="startSlope">Optional slope constraint for the first point. Single.NaN means no constraint.</param>
        /// <param name="endSlope">Optional slope constraint for the final point. Single.NaN means no constraint.</param>
        /// <param name="debug">Turn on console output. Default is false.</param>
        /// <returns>The computed y values for each xs.</returns>
        public static double[] Compute(double[] x, double[] y, double[] xs, double startSlope = double.NaN, double endSlope = double.NaN, bool debug = false)
        {
            CubicSpline spline = new CubicSpline();

            return(spline.FitAndEval(x, y, xs, startSlope, endSlope, debug));
        }