/// <summary>Recalculates the internal lookup table so that the bezier can be sampled by distance or by uniform t-values. /// Only call this before sampling a different curve, or if the curve has changed shape since last time it was calculated</summary> /// <param name="bezier">The curve to use when sampling</param> public void Recalculate(BezierCubic2D bezier) { float cumulativeLength = 0; Vector2 prevPt = bezier.P0; cumulativeDistances[0] = 0; for (int i = 1; i < resolution; i++) // todo: could optimize by moving all points so that p0 = (0,0) { Vector2 pt = bezier.GetPoint(i / (resolution - 1f)); cumulativeLength += Vector2.Distance(prevPt, pt); cumulativeDistances[i] = cumulativeLength; prevPt = pt; } }
// The way the point recalculation works right now is pretty naive, and doesn't handle extreme acceleration very well. // Right now you need around 30 samples to properly sample, which, is a lot #region Constructors & Point recalc /// <summary>Creates a sampler that can be used to sample a bezier curve by distance or by uniform t-values. /// You'll need to call sampler.Recalculate(bezier) to recalculate if the curve changes shape after this points. /// Recommended resolution for animation: [8-16] /// Recommended resolution for even point spacing: [16-50]</summary> /// <param name="bezier">The curve to use when sampling</param> /// <param name="resolution">The accuracy of this sampler. /// Higher values are more accurate, but are more costly to calculate for every new bezier shape</param> public BezierSampler(BezierCubic2D bezier, int resolution = 12) { this.resolution = resolution; cumulativeDistances = new float[resolution]; Recalculate(bezier); }