getUtoTmapping method

double getUtoTmapping(
  1. double u, [
  2. double? distance
])

Given u in the range ( 0 .. 1 ), returns t also in the range ( 0 .. 1 ). u and t can then be used to give you points which are equidistant from the ends of the curve, using getPoint.

Implementation

double getUtoTmapping(double u, [double? distance]) {
  final arcLengths = getLengths(null);

  int i = 0;
  int il = arcLengths.length;

  double targetArcLength; // The targeted u distance value to get

  if (distance != null) {
    targetArcLength = distance;
  } else {
    targetArcLength = u * arcLengths[il - 1];
  }

  // binary search for the index with largest value smaller than target u distance

  int low = 0, high = il - 1;
  double comparison;

  while (low <= high) {
    i = (low + (high - low) / 2).floor(); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all doublebers are floats

    comparison = arcLengths[i] - targetArcLength;

    if (comparison < 0) {
      low = i + 1;
    } else if (comparison > 0) {
      high = i - 1;
    } else {
      high = i;
      break;

      // DONE

    }
  }

  i = high;

  if (arcLengths[i] == targetArcLength) {
    return i / (il - 1);
  }

  // we could get finer grain at lengths, or use simple interpolation between two points

  final lengthBefore = arcLengths[i];
  final lengthAfter = arcLengths[i + 1];

  final segmentLength = lengthAfter - lengthBefore;

  // determine where we are between the 'before' and 'after' points

  final segmentFraction = (targetArcLength - lengthBefore) / segmentLength;

  // add that fractional amount to t

  final t = (i + segmentFraction) / (il - 1);

  return t;
}