Interpolation
Ludis Langens
ludis at cruzers.com
Mon Apr 13 18:59:28 GMT 1998
<thormj at iname.com> wrote:
> Solution #2:
> Can anyone provide me with a *quick* 2 point linear interpolation
> (1d map)... and a quick 4 point interpolation (2d map)?
>
> My current code looks like:
> return (x-curve[i-1].x)*(curve[i].y - curve[i-1].y)/
> (curve[i].x - curve[i-1].x) + curve[i-1].y;
>
> This is for a 68hc11 uC, so the less math the better. :-/
What is that code fragment trying to do? And why do you have both an x
and a y in each array element?
Here's what GM uses (on a 68xx) to interpolate in a one dimensional
array. "scale" is usually 16 which means that a 17 byte table maps all
input byte values. "scale" of 8 allows a 9 byte table. Other values
are also possible.
typedef unsigned char uchar;
uchar Interpolate(uchar *table, uchar input, uchar scale)
{
unsigned int temp;
uchar whole, fract;
temp = input * scale;
whole = temp >> 8;
fract = temp & 0xff;
table += whole;
if (table[0] <= table[1])
return table[0] + (((table[1] - table[0]) * fract + 0x80) >> 8);
else
return table[0] - (((table[0] - table[1]) * fract + 0x80) >> 8);
}
For a two dimensional array, the above algorithm gets used three times:
once in row n, once in row n + 1, and once more on the previous two
results.
To interpolate or not to interpolate: The main reason to interpolate is
likely not the increased accuracy. Instead, interpolating gets rid of a
step function in the output value. Control algorithms won't work good
when a table lookup doesn't produce a smooth output.
unsigned long BinToBCD(unsigned long i) {unsigned long t;
Ludis Langens return i ? (t = BinToBCD(i >> 1), (t << 1) + (i & 1) +
ludis at cruzers.com (t + 858993459 >> 2 & 572662306) * 3) : 0;}
More information about the Diy_efi
mailing list