Ten Minute Physics - 11 Finding overlaps among thousands of objects blazing fast
모든 입자에 대해 어떤 입자 하나가 다른 입자와 충돌했는지 확인하려면 걸림.
→ 공간을 격자로 나누고 해당 입자가 속한 칸과 주변 칸에 있는 입자들만 검사 해 수준으로 감소
→ 무한히 넓은 공간을 다룰 때에는 격자를 미리 만들기엔 메모리 부족 문제가 발생할 수 있어 유한한 메모리 주소로 매핑하는 해시 테이블을 사용.
격자 좌표 계산(Discretization)
해시 함수(Hashing)
h = (xi * 92837111) ^ (yi * 689287499) ^ (zi * 283923481);
hashIndex = abs(h) % tableSize;
→ 같은 해시 공간에 들어있는 입자들이 실제로는 멀리 떨어져 있을 수 있지만, 이를 별도로 엄격하게 해결하지 않고 허용함. 이는 이후 단계에서 실제 거리 검사 를 수행해 무시됨.
데이터 구축(Creating the Table)
create(pos) {
var numObjects = Math.min(pos.length / 3, this.cellEntries.length);
// determine cell sizes
this.cellStart.fill(0);
this.cellEntries.fill(0);
for (var i = 0; i < numObjects; i++) {
var h = this.hashPos(pos, i);
this.cellStart[h]++;
}
// determine cells starts
var start = 0;
for (var i = 0; i < this.tableSize; i++) {
start += this.cellStart[i];
this.cellStart[i] = start;
}
this.cellStart[this.tableSize] = start; // guard
// fill in objects ids
for (var i = 0; i < numObjects; i++) {
var h = this.hashPos(pos, i);
this.cellStart[h]--;
this.cellEntries[this.cellStart[h]] = i;
}
}