/// <summary> /// Gets points on the path that are evenly spaced with given value. /// </summary> /// <param name="spacing">Distance between points.</param> /// <param name="resolution">Time value.</param> /// <returns>Array of points that are evenly spaced on the curve.</returns> public Vector2[] CalculateEvenlySpacedPoints(float spacing, float resolution = 1) { var evenlySpacedPoints = new List <Vector2> { points[0] }; Vector2 lastPoint = points[0]; float distanceSinceLastEvenPoint = 0; for (int i = 0; i < SegmentsCount; i++) { Vector2[] pointsInSegment = GetPointsInSegment(i); float controlNetLength = Vector2.Distance(pointsInSegment[0], pointsInSegment[1]) + Vector2.Distance(pointsInSegment[1], pointsInSegment[2]) + Vector2.Distance(pointsInSegment[2], pointsInSegment[3]); float estimatedCurveLength = Vector2.Distance(pointsInSegment[0], pointsInSegment[3]) + (controlNetLength / 2); int divisions = Mathf.CeilToInt((estimatedCurveLength * resolution) * 10); float t = 0; while (t <= 1) { t += 1.0f / divisions; // Get point on the curve Vector2 pointOnCurve = BezierHelper.EvaluateCubic(pointsInSegment[0], pointsInSegment[1], pointsInSegment[2], pointsInSegment[3], t); distanceSinceLastEvenPoint += Vector2.Distance(lastPoint, pointOnCurve); /* * If distance between the last point and the new one is less than spacing, then just ignore that new point. * Otherwise if the distance is equal to spacing, add that point to evenly spaced points. * And if the distance is more than spacing, then move that point back so that the distance becomes equal to * spacing and that point to evenly spaced points. */ while (distanceSinceLastEvenPoint >= spacing) { float overshootDistance = distanceSinceLastEvenPoint - spacing; Vector2 newEvenlySpacedPoint = pointOnCurve + ((lastPoint - pointOnCurve).normalized * overshootDistance); evenlySpacedPoints.Add(newEvenlySpacedPoint); distanceSinceLastEvenPoint = overshootDistance; lastPoint = newEvenlySpacedPoint; } lastPoint = pointOnCurve; } } return(evenlySpacedPoints.ToArray()); }