evaluate method

dynamic evaluate(
  1. double t
)

Implementation

evaluate(double t) {
  var pp = parameterPositions;
  int i1 = _cachedIndex;

  num? t1;
  num? t0;

  if (i1 < pp.length) {
    t1 = pp[i1];
  }
  if (i1 - 1 >= 0) {
    t0 = pp[i1 - 1];
  }

  validate_interval:
  {
    seek:
    {
      int right;

      linear_scan:
      {
        //- See http://jsperf.com/comparison-to-undefined/3
        //- slower code:
        //-
        //- 				if ( t >= t1 || t1 == null ) {
        forward_scan:
        if (t1 == null || t >= t1) {
          for (var giveUpAt = i1 + 2;;) {
            if (t1 == null) {
              if (t < t0!) break forward_scan;

              // after end

              i1 = pp.length;
              _cachedIndex = i1;
              return afterEnd(i1 - 1, t, t0);
            }

            if (i1 == giveUpAt) break; // this loop

            t0 = t1;

            int _idx = ++i1;

            if (_idx < pp.length) {
              t1 = pp[_idx];
            } else {
              t1 = null;
            }

            if (t1 != null && t < t1) {
              // we have arrived at the sought interval
              break seek;
            }
          }

          // prepare binary search on the right side of the index
          right = pp.length;
          break linear_scan;
        }

        //- slower code:
        //-					if ( t < t0 || t0 == null ) {
        if (t0 == null || !(t >= t0)) {
          // looping?

          var t1global = pp[1];

          if (t < t1global) {
            i1 = 2; // + 1, using the scan for the details
            t0 = t1global;
          }

          // linear reverse scan

          for (var giveUpAt = i1 - 2;;) {
            if (t0 == null) {
              // before start

              _cachedIndex = 0;
              return beforeStart(0, t, t1);
            }

            if (i1 == giveUpAt) break; // this loop

            t1 = t0;

            int iii = --i1 - 1;
            if (iii < 0) {
              t0 = null;
            } else {
              t0 = pp[iii];
            }

            if (t0 != null && t >= t0) {
              // we have arrived at the sought interval
              break seek;
            }
          }

          // prepare binary search on the left side of the index
          right = i1;
          i1 = 0;
          break linear_scan;
        }

        // the interval is valid

        break validate_interval;
      } // linear scan

      // binary search

      while (i1 < right) {
        var mid = (i1 + right) >> 1;

        // print(" Interpolant i1: ${i1} right: ${right} pp: ${pp.length} mid: ${mid} ");

        if (t < pp[mid]) {
          right = mid;
        } else {
          i1 = mid + 1;
        }
      }

      t1 = null;
      t0 = null;

      if (i1 < pp.length) {
        t1 = pp[i1];
      }
      if (i1 - 1 < pp.length) {
        t0 = pp[i1 - 1];
      }

      // check boundary cases, again

      if (t0 == null) {
        _cachedIndex = 0;
        return beforeStart(0, t, t1);
      }

      if (t1 == null) {
        i1 = pp.length;
        _cachedIndex = i1;
        return afterEnd(i1 - 1, t0, t);
      }
    } // seek

    _cachedIndex = i1;

    intervalChanged(i1, t0, t1);
  } // validate_interval

  return interpolate(i1, t0, t, t1!);
}