Skip to content

Instantly share code, notes, and snippets.

@ClickerMonkey
Created August 30, 2014 00:56
Show Gist options
  • Save ClickerMonkey/ce34f989661b6d4d6275 to your computer and use it in GitHub Desktop.
Save ClickerMonkey/ce34f989661b6d4d6275 to your computer and use it in GitHub Desktop.
Interpolation between two integers taking N moves without using floats and avoiding division and modulus.
package org.magnos.path;
import static org.junit.Assert.*;
import org.junit.Test;
public class TestIntlerp
{
public class Intlerp
{
public int value, jump, error, errorIncrement, errorMax, sign;
public void reset(int start, int end, int moves) {
int signedGap = end - start;
int gap = Math.abs( signedGap );
value = start;
sign = Integer.signum( signedGap );
jump = signedGap / moves;
errorMax = moves;
errorIncrement = Math.min( gap - (moves * Math.abs( jump )), moves );
error = moves >> 1;
}
public int next() {
value += jump;
error += errorIncrement;
if (error >= errorMax) {
value += sign;
error -= errorMax;
}
return value;
}
}
@Test
public void test()
{
final int BOUNDS = 128;
final int N_MAX = 256;
Intlerp x = new Intlerp();
for (int a = -BOUNDS; a < BOUNDS; a++)
{
for (int b = -BOUNDS; b < BOUNDS; b++)
{
for (int N = 2; N < N_MAX; N++)
{
runTest( x, a, b, N );
}
}
}
}
public void runTest( Intlerp x, int a, int b, int N )
{
x.reset(a, b, N);
for (int i = 0; i < N; i++) {
x.next();
}
assertEquals( String.format( "%d to %d in %d", a, b, N), b, x.value );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment