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]); }
/// <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()); }
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]); }
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); }
/// <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); } } }