Re: Fast Interpolation given Left, Right, Intermediate and a shift value.

Skybuck Flying <[email protected]> Sat, 4 Jun 2022 15:44:05 -0700 (PDT)
Newsgroups alt.comp.lang.borland-delphi
Message-ID <[email protected]>
Well first of all the parameters inside the formula would have to be swapped.

With a little bit of help from this link and code I came to the following routine/solution which is very close, but "ofcourse" not 100% the same.

https://www.gamedev.net/forums/topic/337531-integer-interpolation/3198110/

and the code from DavW:

// slow division example:
inline int interpolate(int a, int b, int percentage) {    return (a*percentage)/100+(b*(100-percentage)/100);}

// fast shifting example:
// Revised version (position is between 0 and 256):
inline int interpolate(int a, int b, int position) {    return (a * position) >> 8 + (b * (256-position)) >> 8;}

Converted to Delphi and modified/adjusted/swapped around for my purposes:

function Linear_InterpolateFast( Left, Right, Intermediate, Shift : Integer ) : integer;
var
	check_x,
	check_a,
	check_b,
	check_compare : double;
begin
	// good:
	result :=
//		(left * ( (1 shl shift)-Intermediate)) shr shift +
//		(right * Intermediate) shr shift;

		// can be written as and is also more accurate:

		(
			(left * ( (1 shl shift)-Intermediate)) +
			(right * Intermediate)
		)
		shr shift;

	// but still not as accurate as this, some combinations are not the same:
	check_x := Intermediate / (1 shl shift);
	check_a := left;
	check_b := right;
	check_compare := check_a*(1-check_x) + check_b*check_x;

	if round(check_compare) <> result then
	begin
	    result := 0; // error detected
	end;
end;

Question is can you do better, speed-wise, or accuracy-wise maintaining the speed of this function ?

Have not benchmarked anything, but my main concern is avoiding the expensive division: Intermediate/31 which is now avoided with this routine above.

The check stuff is to compared against doubles.

Bye for now,
  Skybuck.

P.S.: Sorry for sloppy Delphi code, could have written it a bit better, but I've been busy all day.