cutAndShift method

MeasuredPolygon cutAndShift(
  1. double cuttingPoint
)

Implementation

MeasuredPolygon cutAndShift(double cuttingPoint) {
  if (cuttingPoint < 0 && cuttingPoint > 1) {
    throw ArgumentError('Cutting point is expected to be between 0 and 1');
  }

  if (cuttingPoint < distanceEpsilon) return this;

  final targetIndex = _cubics.indexWhere(
    (c) =>
        cuttingPoint >= c._startOutlineProgress &&
        cuttingPoint <= c._endOutlineProgress,
  );
  final target = _cubics[targetIndex];

  final (b1, b2) = target.cutAtProgress(cuttingPoint);

  final retCubics = [b2.cubic];
  for (var i = 1; i < _cubics.length; i++) {
    retCubics.add(_cubics[(i + targetIndex) % _cubics.length].cubic);
  }
  retCubics.add(b1.cubic);

  final retOutlineProgress = List<double>.filled(_cubics.length + 2, 0);

  for (var i = 0; i < _cubics.length + 2; i++) {
    if (i == 0) {
      retOutlineProgress[i] = 0;
    } else if (i == _cubics.length + 1) {
      retOutlineProgress[i] = 1;
    } else {
      final cubicIndex = (targetIndex + i - 1) % _cubics.length;
      retOutlineProgress[i] = positiveModulo(
        _cubics[cubicIndex]._endOutlineProgress - cuttingPoint,
        1,
      );
    }
  }

  final newFeatures = [
    for (var i = 0; i < _features.length; i++)
      ProgressableFeature(
        positiveModulo(_features[i].progress - cuttingPoint, 1),
        _features[i].feature,
      ),
  ];

  return MeasuredPolygon._(
    measurer: _measurer,
    features: newFeatures,
    cubics: retCubics,
    outlineProgress: retOutlineProgress,
  );
}