// todo: not cut by rhythm private SliderTick[] GetBezierDiscreteBallData(double interval) { if (Math.Round(interval - _singleElapsedTime) >= 0) { return(Array.Empty <SliderTick>()); } var totalLength = RawBezierLengthData.Sum(); var ticks = new List <SliderTick>(); for (int i = 1; i *interval < _singleElapsedTime; i++) { var offset = i * interval; // 当前tick的相对时间 if (Edges.Any(k => Math.Abs(k.Offset - _offset - offset) < 0.01)) { continue; } var ratio = offset / _singleElapsedTime; // 相对整个滑条的时间比例,=距离比例 var relativeLen = totalLength * ratio; // 至滑条头的距离 var(index, lenInPart) = CalculateWhichPart(relativeLen); // can be optimized var len = RawBezierLengthData[index]; var tickPoint = Bezier.CalcPoint((float)(lenInPart / len), RawGroupedBezierData[index]); ticks.Add(new SliderTick(_offset + offset, tickPoint)); } if (Repeat > 1) { var firstSingleCopy = ticks.ToArray(); for (int i = 2; i <= Repeat; i++) { var reverse = i % 2 == 0; if (reverse) { ticks.AddRange(firstSingleCopy.Reverse().Select(k => new SliderTick((_singleElapsedTime - (k.Offset - _offset)) + (i - 1) * _singleElapsedTime + _offset, k.Point))); } else { ticks.AddRange(firstSingleCopy.Select(k => new SliderTick(k.Offset + (i - 1) * _singleElapsedTime, k.Point))); } } } return(ticks.ToArray()); }