2013-01-31

Robust Lerp

ryg writes about lerp:

http://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/

lerp_1 is considered the robust formulation, but I ran into a practical problem with it in my work. My colleague Travis Heppe suggested this alternative (in Javascript for convenience):

----

function lerp_3(t, a, b) {
  var bma = b - a;
  if (t < 0.5) {
    return a + bma * t;
  } else {
    return b - bma * (1 - t);
  }
}

----

Which seems to meet all my criteria. A JS console session showing test cases:

----

function lerp_1(t, a, b) { return (1 - t)*a + t*b; }
function lerp_2(t, a, b) { return a + t * (b - a); }
function lerp_3(t, a, b) { var bma = b - a; if (t < 0.5) { return a + bma * t; } else { return b - bma * (1 - t); } }

// lerp_1 failure case:
lerp_1(5.0586262771736122e-15, 127, 127);
// --> 126.99999999999999
lerp_2(5.0586262771736122e-15, 127, 127);
// --> 127
lerp_3(5.0586262771736122e-15, 127, 127);
// --> 127

// lerp_2 failure case:
lerp_1(1, 1.1805916083717324e+21, 0.000001430511474609375);
// --> 0.000001430511474609375
lerp_2(1, 1.1805916083717324e+21, 0.000001430511474609375);
// --> 0
lerp_3(1, 1.1805916083717324e+21, 0.000001430511474609375);
// --> 0.000001430511474609375

// [added 2013-02-14]
// An even simpler lerp_1 failure case, thanks to Morton Ofstad:
lerp_1(0.4, 1.7, 1.7)
// --> 1.7000000000000002

----

Associated G+ post

tu@tulrich.com