public OrientedPoint[] CalculateEvenlySpaceOrientedPoints(float spacing, float resolution = 1.0f) { List <OrientedPoint> spacedPoints = new List <OrientedPoint>(); spacedPoints.Add(new OrientedPoint(points[0])); var previousPoint = new OrientedPoint(points[0]); float distanceFromPrevious = 0f; for (int segIndex = 0; segIndex < NumSegments; ++segIndex) { Vector3[] p = GetPointsInSegment(segIndex); float controlNetLength = Vector3.Distance(p[0], p[1]) + Vector3.Distance(p[1], p[2]) + Vector3.Distance(p[2], p[3]); float estimatedCurveLEngth = Vector3.Distance(p[0], p[3]) + (controlNetLength * 0.5f); int divisions = (int)estimatedCurveLEngth * (int)resolution * 10; var pointStart = Bezier.EvaluateCubicOriented(p[0], p[1], p[2], p[3], 0.0f); spacedPoints.Add(pointStart); previousPoint = pointStart; float t = 0f; while (t < 1f) { t += 1f / divisions; var poc = Bezier.EvaluateCubicOriented(p[0], p[1], p[2], p[3], t); distanceFromPrevious += Vector3.Distance(previousPoint.position, poc.position); while (distanceFromPrevious >= spacing) { float overShoot = distanceFromPrevious - spacing; Vector3 newPoint = poc.position + (previousPoint.position - poc.position).normalized * overShoot; float deltaLen = (newPoint - previousPoint.position).magnitude; float percent = overShoot / deltaLen; Quaternion newOritentation = Quaternion.Slerp(previousPoint.orientation, poc.orientation, percent); spacedPoints.Add(new OrientedPoint(newPoint, newOritentation)); distanceFromPrevious = overShoot; previousPoint = new OrientedPoint(newPoint); } previousPoint = poc; } var pointFinal = Bezier.EvaluateCubicOriented(p[0], p[1], p[2], p[3], 1.0f); spacedPoints.Add(pointFinal); previousPoint = pointFinal; } return(spacedPoints.ToArray()); }