I wrote this in Python based on the comments seen here,
l = 5 n = 5 p1,p2,p3 = 73856093, 19349663, 83492791 x1 = [33,4,11] x2 = [31,1,14] x3 = [10,44,19] def spatial_hash(x): ix,iy,iz = np.floor(x[0]/l), np.floor(x[1]/l), np.floor(x[2]/l) return (int(ix*p1) ^ int(iy*p2) ^ int(iz*p3)) % n print (spatial_hash(x1)) print (spatial_hash(x2)) print (spatial_hash(x3))
It gives
1 1 3
It seemed to work.
In C++
#include <cstdlib> #include <iostream> #include <unordered_map> #include <vector> #include <random> #include <eigen3/Eigen/Dense> using namespace Eigen; using namespace std; const int HASH_SIZE = 200; //const float MAX = 500.0; const float L = 0.2f; const float mmin = -1.f; const float mmax = 1.f; unordered_map<int, vector<Vector3d>> map ; inline size_t hasha(Vector3d &p) { int ix = (unsigned int)((p[0]+2.f) / L); int iy = (unsigned int)((p[1]+2.f) / L); int iz = (unsigned int)((p[2]+2.f) / L); return (unsigned int)((ix * 73856093) ^ (iy * 19349663) ^ (iz * 83492791)) % HASH_SIZE; } int main(int argc, char** argv) { std::default_random_engine generator; std::uniform_real_distribution<double> distribution(-1.0,1.0); for(size_t i=0;i<300;i++){ float x = distribution(generator); float y = distribution(generator); float z = distribution(generator); Vector3d v(x,y,z); std::cout << hasha(v) << " " << v[0] << " " << v[1] << " " << v[2] << std::endl; map[hasha(v)].push_back(v); vector<Vector3d> entry = map[hasha(v)]; std::cout << "size " << entry.size() << std::endl; } for (const auto & [ key, value ] : map) { cout << key << std::endl; vector<Vector3d> v = map[key]; float average = 0.0f; for (int i=0; i<v.size(); i++){ for (int j=0; j<v.size(); j++){ if (i!=j){ Vector3d v1 = v[i]; Vector3d v2 = v[j]; std::cout << " dist " << (v1-v2).norm() << std::endl; } } } } }