/// <summary>
        /// Create a new collection of key points with cumulative values.
        /// </summary>
        /// <param name = "typeProvider">
        /// The provider which gives information about the type, required to do interpolation between the key points.
        /// </param>
        public CumulativeKeyPointCollection(AbstractTypeInterpolationProvider <TValue, TMath> typeProvider)
            : base(typeProvider)
        {
            _zero = CastOperator <double, TMath> .Cast(0);

            _minusOne = CastOperator <double, TMath> .Cast(-1);
        }
예제 #2
0
        /// <summary>
        /// Retrieve values for all dimensions for all 4 control points.
        /// </summary>
        /// <returns>
        /// A 2 dimensional array with all the dimension values for all 4 control points.
        /// The first dimension of the array indicates the control point, the second the dimension.
        /// </returns>
        double[][] RetrieveValues(int smallerIndex, int biggerIndex, AbstractTypeInterpolationProvider <TValue, TMath> typeProvider)
        {
            // Retrieve required values.
            TValue p0 = KeyPoints[smallerIndex != 0 ? smallerIndex - 1 : smallerIndex];
            TValue p1 = KeyPoints[smallerIndex];
            TValue p2 = KeyPoints[biggerIndex];
            TValue p3 = KeyPoints[biggerIndex != KeyPoints.Count - 1 ? biggerIndex + 1 : biggerIndex];

            // Retrieve required dimension values.
            double[] p0Values = typeProvider.GetDimensionValues(p0).Cast <double>().ToArray();
            double[] p1Values = typeProvider.GetDimensionValues(p1).Cast <double>().ToArray();
            double[] p2Values = typeProvider.GetDimensionValues(p2).Cast <double>().ToArray();
            double[] p3Values = typeProvider.GetDimensionValues(p3).Cast <double>().ToArray();

            return(new[] { p0Values, p1Values, p2Values, p3Values });
        }
예제 #3
0
        protected override TValue TangentAt(int smallerIndex, int biggerIndex, TMath position, double percentage)
        {
            AbstractTypeInterpolationProvider <TValue, TMath> typeProvider = KeyPoints.TypeProvider;

            // Retrieve values for all dimensions for all 4 control points.
            double[][] values = RetrieveValues(smallerIndex, biggerIndex, typeProvider);

            // Set up hermite base function derivatives.
            double t              = percentage;
            double t2             = Math.Pow(t, 2);
            double baseFunction00 = (6 * t2) - (6 * t);
            double baseFunction10 = (3 * t2) - (4 * t) + 1;
            double baseFunction01 = (6 * t) - (6 * t2);
            double baseFunction11 = (3 * t2) - (2 * t);

            // Get tangent by calculating derivative.
            double tension = 1 - Tension;

            TMath[] tangent = new TMath[typeProvider.AmountOfDimensions];
            for (int i = 0; i < typeProvider.AmountOfDimensions; ++i)
            {
                // Original: (((2*t^3)-(3*t^2)+1)*b) + (((-2*t^3)+(3*t^2))*c) + ((t^3-(2*t^2)+t)*(n*(c-a))) + ((t^3-t^2)*(n*(d-b)))
                // First derivative: ((3*d+3*c-3*b-3*a)*n-6*c+6*b)*t^2 + ((-2*d-4*c+2*b+4*a)*n+6*c-6*b)*t + (c-a)*n

                // Calculate tangents.
                double tangentSmaller = tension * (values[2][i] - values[0][i]);
                double tangentBigger  = tension * (values[3][i] - values[1][i]);

                // Multiply derived hermite base functions with the points (and tangents) and sum up.
                double result =
                    (baseFunction00 * values[1][i])
                    + (baseFunction01 * values[2][i])
                    + (baseFunction10 * tangentSmaller)
                    + (baseFunction11 * tangentBigger);

                // Sum up all functions.
                tangent[i] = CastOperator <double, TMath> .Cast(result);
            }

            return(typeProvider.CreateInstance(position, tangent));
        }
        protected override TValue Interpolate(int smallerIndex, int biggerIndex, TMath position, double percentage)
        {
            AbstractTypeInterpolationProvider <TValue, TMath> typeProvider = KeyPoints.TypeProvider;

            // Retrieve required values.
            TValue smaller = KeyPoints[smallerIndex];
            TValue bigger  = KeyPoints[biggerIndex];

            // Retrieve required dimension values.
            TMath[] smallerValues = typeProvider.GetDimensionValues(smaller);
            TMath[] biggerValues  = typeProvider.GetDimensionValues(bigger);

            // Linear interpolation.
            TMath[] interpolated = new TMath[typeProvider.AmountOfDimensions];
            for (int i = 0; i < typeProvider.AmountOfDimensions; ++i)
            {
                var valueRange = new Interval <TMath>(smallerValues[i], biggerValues[i]);
                interpolated[i] = valueRange.GetValueAt(percentage);
            }

            return(typeProvider.CreateInstance(position, interpolated));
        }
예제 #5
0
        protected override TValue Interpolate(int smallerIndex, int biggerIndex, TMath position, double percentage)
        {
            AbstractTypeInterpolationProvider <TValue, TMath> typeProvider = KeyPoints.TypeProvider;

            // Retrieve values for all dimensions for all 4 control points.
            double[][] values = RetrieveValues(smallerIndex, biggerIndex, typeProvider);

            // Set up hermite base functions.
            double t              = percentage;
            double t2             = Math.Pow(t, 2);
            double t3             = Math.Pow(t, 3);
            double baseFunction00 = (2 * t3) - (3 * t2) + 1;
            double baseFunction10 = t3 - (2 * t2) + t;
            double baseFunction01 = (-2 * t3) + (3 * t2);
            double baseFunction11 = t3 - t2;

            // Interpolate.
            double tension = 1 - Tension;

            TMath[] interpolated = new TMath[typeProvider.AmountOfDimensions];
            for (int i = 0; i < typeProvider.AmountOfDimensions; ++i)
            {
                // Calculate tangents.
                double tangentSmaller = tension * (values[2][i] - values[0][i]);
                double tangentBigger  = tension * (values[3][i] - values[1][i]);

                // Multiply hermite base functions with the points (and tangents) and sum up.
                double result =
                    (baseFunction00 * values[1][i])
                    + (baseFunction01 * values[2][i])
                    + (baseFunction10 * tangentSmaller)
                    + (baseFunction11 * tangentBigger);

                // Sum up all functions.
                interpolated[i] = CastOperator <double, TMath> .Cast(result);
            }

            return(typeProvider.CreateInstance(position, interpolated));
        }
예제 #6
0
 /// <summary>
 /// Create a new interpolation provider which can interpolate over AbsoluteKeyPoints.
 /// </summary>
 public AbsoluteKeyPointInterpolationProvider(AbstractTypeInterpolationProvider <TValue, TMath> keyPointInterpolationProvider)
     : base(keyPointInterpolationProvider.AmountOfDimensions)
 {
     _keyPointInterpolationProvider = keyPointInterpolationProvider;
 }
예제 #7
0
 /// <summary>
 /// Create a new collection of key points.
 /// </summary>
 /// <param name = "typeProvider">
 /// The provider which gives information about the type, required to do interpolation between the key points.
 /// </param>
 protected AbstractKeyPointCollection(AbstractTypeInterpolationProvider <TValue, TMath> typeProvider)
 {
     TypeProvider = typeProvider;
 }
 /// <summary>
 /// Create a new collection of key points with absolute values.
 /// </summary>
 /// <param name = "typeProvider">
 /// The provider which gives information about the type, required to do interpolation between the key points.
 /// </param>
 /// <param name = "referenceKeyPoint">
 /// A key point which is used to measure the distance to all other added key points.
 /// Don't adjust this key point after adding it.
 /// </param>
 public AbsoluteKeyPointCollection(AbstractTypeInterpolationProvider <TValue, TMath> typeProvider, TValue referenceKeyPoint)
     : base(typeProvider)
 {
     _referenceKeyPoint = referenceKeyPoint;
 }