The book Real-Time Collision Detection, Christer Ericson, page 288, talks about 1D hashing.
// Cell position
struct Cell
{
Cell(int32 px, int32 py, int32 pz)
{
x = px; y = py; z = pz;
}
int32 x, y, z;
};
#define NUM_BUCKETS 1024
// Computes hash bucket index in range [0, NUM_BUCKETS-1]
int32 ComputeHashBucketIndex(Cell cellPos)
{
const int32 h1 = 0x8da6b343; // Large multiplicative constants;
const int32 h2 = 0xd8163841; // here arbitrarily chosen primes
const int32 h3 = 0xcb1ab31f;
int32 n = h1 * cellPos.x + h2 * cellPos.y + h3 * cellPos.z;
n = n % NUM_BUCKETS;
if (n < 0)
{
n += NUM_BUCKETS;
}
return n;
}
I need a hash function that will take any coordinate (x, y)
and convert a 2D grid index (i, j)
where i, j : >= 0 && <= gridDim-1
.
So, I wrote this:
public class HashMaker
{
public int Dimension { get; private set; }
public HashMaker(){}
public HashMaker(int dim)
{
Dimension = dim;
}
public (int i, int j) GetHash(int x, int y)
{
if (Dimension <= 0)
{
throw new InvalidOperationException("Dimension must be greater than zero.");
}
const uint h1 = 0x8da6b343; // Large multiplicative constants;
const uint h2 = 0xd8163841; // here arbitrarily chosen primes
uint n = h1 * (uint)x;
n = n % (uint)Dimension;
if (n < 0) n += (uint)Dimension;
int i= (int)n;
uint m = h1 * (uint)x + h2 * (uint)y;
m = m % (uint)Dimension;
if (m < 0) m += (uint)Dimension;
int j = (int)m;
return (i, j);
}
}
However, GetHash()
is giving unpredictable values.
How can I fix GetHash()
?