예제 #1
0
        /// <summary>
        /// Calculate the outgoing tangent.
        /// </summary>
        /// <param name="previousControlPoint"></param>
        /// <param name="nextControlPoint"></param>
        /// <returns></returns>
        public Vector3 CalculateDestinationTangent(KochanekBartelsControlPoint previousControlPoint, KochanekBartelsControlPoint nextControlPoint)
        {
            var factor1 = (1 - Tension) * (1 + Continuity) * (1 + Bias) / 2;
            var factor2 = (1 - Tension) * (1 - Continuity) * (1 - Bias) / 2;

            return(factor1 * (Position - previousControlPoint.Position) + factor2 * (nextControlPoint.Position - Position));
        }
예제 #2
0
        /// <summary>
        /// Calculate one segment.
        /// </summary>
        /// <param name="point1"></param>
        /// <param name="point2"></param>
        /// <param name="point3"></param>
        /// <param name="point4"></param>
        /// <param name="steps">Steps for this segement, between point2 and point3.</param>
        /// <returns></returns>
        private static List <Vector3> InterpolateSegment(KochanekBartelsControlPoint point1, KochanekBartelsControlPoint point2, KochanekBartelsControlPoint point3, KochanekBartelsControlPoint point4, int steps, bool isLastSegment = false)
        {
            var interpolatedPoints = new List <Vector3>();

            Vector3 point2DestinationTangent = point2.CalculateDestinationTangent(point1, point3);
            Vector3 point3SourceTangent      = point3.CalculateSourceTangent(point2, point4);

            for (var i = 0; i < steps; i++)
            {
                float s;
                if (isLastSegment)
                {
                    s = i / (float)(steps - 1);
                }
                else
                {
                    s = i / (float)(steps);
                }

                var newPoint = CalculateInterpolatedPoint(point2.Position, point3.Position, point2DestinationTangent, point3SourceTangent, s);

                interpolatedPoints.Add(newPoint);
            }

            return(interpolatedPoints);
        }
예제 #3
0
        /// <summary>
        /// Insert a control point at index.
        /// </summary>
        /// <param name="index"></param>
        /// <param name="controlPoint"></param>
        public SplineModificationInfo InsertControlPoint(int index, KochanekBartelsControlPoint controlPoint)
        {
            ControlPoints.Insert(index, controlPoint);

            if (ControlPoints.Count < 3 && InterpolatedPoints.Count < 2 * Steps)
            {
                Debug.LogWarning("KochanekBartelsSpline: Control point was added but the line can only be interpolated when there are at least 3 control points.");
                return(new SplineModificationInfo(0, 0, 0));
            }
            else if (ControlPoints.Count == 3 && InterpolatedPoints.Count == Steps)
            {
                this.SetControlPoints(ControlPoints.ToArray());
                return(new SplineModificationInfo(0, Steps, 2 * Steps));
            }
            else if (ControlPoints.Count == 3)
            {
                this.SetControlPoints(ControlPoints.ToArray());
                return(new SplineModificationInfo(0, 0, 2 * Steps));
            }

            //determine which segments have to be reinterpolated
            int start = (index - 2) >= 0 ? (index - 2) : 0;
            int end   = (index + 1) <= (ControlPoints.Count - 2) ? (index + 1) : (ControlPoints.Count - 2);

            for (int i = start; i <= end; i++)
            {
                try
                {
                    if (index == ControlPoints.Count - 1)
                    {
                        //if we are inserting the control point as the new last element
                        //dont try to remove the segment before the new control point because it doesnt exist yet
                        if (i != index - 1)
                        {
                            //dont remove at added index so a new segment is added
                            InterpolatedPoints.RemoveRange(i * Steps, Steps);
                        }
                    }
                    else
                    {
                        if (i != index)
                        {
                            //dont remove at added index so a new segment is added
                            InterpolatedPoints.RemoveRange(i * Steps, Steps);
                        }
                    }
                    InterpolatedPoints.InsertRange(i * Steps, InterpolateSegment(i));
                }
                catch (ArgumentException exception)
                {
                    Debug.LogError("Can't insert control point at index that doesnt exist yet, add instead!\n" + exception);
                }
            }

            return(new SplineModificationInfo(start * Steps, (end - start) * Steps, (end - start + 1) * Steps));
        }
예제 #4
0
        /// <summary>
        /// Reset the existing control point at index.
        /// </summary>
        /// <param name="index"></param>
        /// <param name="controlPoints"></param>
        public SplineModificationInfo SetControlPoint(int index, KochanekBartelsControlPoint controlPoint)
        {
            ControlPoints[index] = controlPoint;

            int start = (index - 2) >= 0 ? (index - 2) : 0;
            int end   = (index + 1) <= (ControlPoints.Count - 2) ? (index + 1) : (ControlPoints.Count - 2);

            for (int i = start; i <= end; i++)
            {
                try
                {
                    InterpolatedPoints.RemoveRange(i * Steps, Steps);
                    InterpolatedPoints.InsertRange(i * Steps, InterpolateSegment(i));
                }
                catch (ArgumentException exception)
                {
                    Debug.LogError("Can't set control point that doesnt exist yet, add instead!\n" + exception);
                }
            }

            return(new SplineModificationInfo(start * Steps, (end - start + 1) * Steps, (end - start + 1) * Steps));
        }
예제 #5
0
 /// <summary>
 /// Add control point at the end of the curve.
 /// </summary>
 /// <param name="controlPoint"></param>
 public SplineModificationInfo AddControlPoint(KochanekBartelsControlPoint controlPoint)
 {
     return(InsertControlPoint(ControlPoints.Count, controlPoint));
 }