evaluate method
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!);
}