Beispiel #1
0
        public void SingleValue()
        {
            var c = new HermiteSpline <double> {
                { 0, 5, 0 }
            };

            Assert.AreEqual(5.0, c[-1]);
            Assert.AreEqual(5.0, c[0]);
            Assert.AreEqual(5.0, c[1]);
        }
Beispiel #2
0
        /// <summary>
        /// Splits a hermite spline at a position.
        /// Note that this may produce more than two output splines in order to eliminate discontinuities.
        /// </summary>
        /// <param name="splitPosition">The position at which to split the spline.</param>
        public static HermiteSpline <T>[] Split <T> (
            this HermiteSpline <T> spline,
            float splitPosition
            )
            where T : struct
        {
            var resultList = new List <HermiteSpline <T> >(4);

            spline.SplitInto(splitPosition, resultList);

            return(resultList.ToArray());
        }
Beispiel #3
0
        public void TwoValues()
        {
            var c = new HermiteSpline <double> {
                { 0, 5, 0 },
                { 1, 10, 0 }
            };

            Assert.AreEqual(5.0, c[-1]);
            Assert.AreEqual(5.0, c[0]);
            Assert.AreEqual(10.0, c[1]);
            Assert.AreEqual(10.0, c[2]);
        }
Beispiel #4
0
        public static HermiteSpline <T> Cardinal(IEnumerable <CurvePoint <T> > points, float tension)
        {
            var result = new HermiteSpline <T>();

            foreach (var pt in points)
            {
                result.Add(pt.Position, pt.Value, default(T));
            }

            result.ConvertToCardinal(tension);

            return(result);
        }
Beispiel #5
0
        /// <summary>
        /// Splits a hermite spline at a position.
        /// Note that this may produce more than two output splines in order to eliminate discontinuities.
        /// </summary>
        /// <param name="splitPosition">The position at which to split the spline.</param>
        /// <param name="output">The list that will receive the new splines created by the split (up to 4).</param>
        public static void SplitInto <T> (
            this HermiteSpline <T> spline,
            float splitPosition,
            List <HermiteSpline <T> > output
            )
            where T : struct
        {
            if ((splitPosition <= spline.Start) || (splitPosition >= spline.End))
            {
                output.Add(spline);
                return;
            }

            int count = spline.Count;
            int splitFirstPoint = spline.GetLowerIndexForPosition(splitPosition), splitSecondPoint = splitFirstPoint + 1;

            HermiteSpline <T> temp;

            if (splitFirstPoint > 0)
            {
                float position;
                T     value, velocity;

                output.Add(temp = new HermiteSpline <T>());
                for (int i = 0, end = splitFirstPoint; i <= end; i++)
                {
                    spline.GetValuesAtIndex(i, out position, out value, out velocity);
                    temp.Add(position, value, velocity);
                }
            }

            float firstPosition = spline.GetPositionAtIndex(splitFirstPoint), secondPosition = spline.GetPositionAtIndex(splitSecondPoint);
            float splitLocalPosition = (splitPosition - firstPosition) / (secondPosition - firstPosition);

            T a = spline.GetValueAtIndex(splitFirstPoint), d = spline.GetValueAtIndex(splitSecondPoint);
            T u = spline.GetDataAtIndex(splitFirstPoint).Velocity, v = spline.GetDataAtIndex(splitSecondPoint).Velocity;
            T b, c;

            CurveUtil.HermiteToCubic(ref a, ref u, ref d, ref v, out b, out c);

            var ab = Arithmetic.Lerp(a, b, splitLocalPosition);
            var bc = Arithmetic.Lerp(b, c, splitLocalPosition);
            var cd = Arithmetic.Lerp(c, d, splitLocalPosition);

            var ab_bc = Arithmetic.Lerp(ab, bc, splitLocalPosition);
            var bc_cd = Arithmetic.Lerp(bc, cd, splitLocalPosition);

            var midpoint = Arithmetic.Lerp(ab_bc, bc_cd, splitLocalPosition);

            T newA, newB, newC, newD, newU, newV;

            newA = a;
            newB = ab;
            newC = ab_bc;
            newD = midpoint;

            CurveUtil.CubicToHermite(ref newA, ref newB, ref newC, ref newD, out newU, out newV);

            output.Add(temp = new HermiteSpline <T>());
            temp.Add(
                firstPosition, newA, newU
                );
            temp.Add(
                splitPosition, newD, newV
                );

            newA = midpoint;
            newB = bc_cd;
            newC = cd;
            newD = d;

            CurveUtil.CubicToHermite(ref newA, ref newB, ref newC, ref newD, out newU, out newV);

            output.Add(temp = new HermiteSpline <T>());
            temp.Add(
                splitPosition, newA, newU
                );
            temp.Add(
                secondPosition, newD, newV
                );

            if (splitSecondPoint < (count - 1))
            {
                float position;
                T     value, velocity;

                output.Add(temp = new HermiteSpline <T>());
                for (int i = splitSecondPoint, end = count - 1; i <= end; i++)
                {
                    spline.GetValuesAtIndex(i, out position, out value, out velocity);
                    temp.Add(position, value, velocity);
                }
            }
        }