xxxxxxxxxx
126
class SpatialGrid {
constructor(cell_size, num_cells, x_origin, y_origin, z_origin) {
this.cell_size = cell_size;
this.num_cells = num_cells;
this.total_cells = num_cells * num_cells * num_cells;
this.origin = createVector(x_origin, y_origin, z_origin);
this.cell_particle_index_lookup = {};
this.cell_neighbor_index_lookup = {};
this.initLookUp();
}
initLookUp() {
for (let i = 0; i < this.total_cells; i++) {
this.cell_particle_index_lookup[i] = new Set();
this.cell_neighbor_index_lookup[i] = new Set();
}
}
/**
* Adds a particle to the cell containing the specified spatial location.
* @param {double} p_i_idx - The index of the particle.
* @param {Vector} pos - Coordinate of the point.
* @returns {int} The index of the cell containing the particle.
*/
addToCell(p_i_idx, pos) {
let cell_idx = this.locationToIndex(pos);
// console.log("p_i_idx", p_i_idx, "cell_idx", cell_idx, "pos", pos.x, pos.y, pos.z, "total cells", this.total_cells);
this.cell_particle_index_lookup[cell_idx].add(p_i_idx);
this.cell_neighbor_index_lookup[cell_idx].add(p_i_idx);
let neighbor_cell_indices = this.getNeighborIndices(cell_idx);
neighbor_cell_indices.forEach(neighbor_idx => {
if (!this.cell_neighbor_index_lookup[neighbor_idx]) {
this.cell_neighbor_index_lookup[neighbor_idx] = new Set();
}
this.cell_neighbor_index_lookup[neighbor_idx].add(p_i_idx);
});
return cell_idx;
}
/**
* Converts a linear index to cell coordinates.
* @param {int} idx - The linear index of the cell.
* @returns {Vector} An array containing the i, j, and k coordinates of the cell.
*/
indexToCellCoord(idx) {
let i = Math.floor(idx / (this.num_cells * this.num_cells));
let j = Math.floor((idx / this.num_cells) % this.num_cells);
let k = idx % this.num_cells;
return createVector(i, j, k);
}
/**
* Converts cell coordinates to a linear index.
* @param {double} i - The i-coordinate of the cell.
* @param {double} j - The j-coordinate of the cell.
* @param {double} k - The k-coordinate of the cell.
* @returns {int} The linear index corresponding to the cell coordinates.
*/
cellCoordToIndex(i, j, k) {
return i * this.num_cells * this.num_cells + j * this.num_cells + k;
}
/**
* Converts spatial coordinates to a cell index.
* @param {Vector} pos - Coordinate of the point.
* @returns {int} The index of the cell containing the spatial location.
*/
locationToIndex(pos) {
// Shift the origin from (0, 0, 0)
// x -= this.origin[0];
// y -= this.origin[1];
// z -= this.origin[2];
let p = p5.Vector.sub(pos, this.origin);
let i = Math.floor(p.x / this.cell_size);
let j = Math.floor(p.y / this.cell_size);
let k = Math.floor(p.z / this.cell_size);
return this.cellCoordToIndex(i, j, k);
}
/**
* Gets the indices of neighboring cells for a given cell index.
* @param {int} cell_idx - The index of the cell.
* @returns {Array<int>} An array containing the indices of neighboring cells.
*/
getNeighborIndices(cell_idx) {
let cell_coord = this.indexToCellCoord(cell_idx);
let i = cell_coord.x;
let j = cell_coord.y;
let k = cell_coord.z;
let neighbor_cell_indices = [];
for (let di = -1; di <= 1; di++) {
for (let dj = -1; dj <= 1; dj++) {
for (let dk = -1; dk <= 1; dk++) {
if (i + di < 0 || i + di >= this.num_cells) continue;
if (j + dj < 0 || j + dj >= this.num_cells) continue;
if (k + dk < 0 || k + dk >= this.num_cells) continue;
let neighbor_cell_idx = this.cellCoordToIndex(i + di, j + dj, k + dk);
neighbor_cell_indices.push(neighbor_cell_idx);
}
}
}
return neighbor_cell_indices;
}
/**
* Gets the total double of cells in the grid.
* @returns {int} The total number of cells.
*/
getTotalCells() {
return this.total_cells; // Return the total number of cells in the grid
}
/**
* Gets the double of cells along one dimension of the grid.
* @returns {int} The number of cells along one dimension.
*/
getNumCells() {
return this.num_cells; // Return the number of cells along one dimension of the grid
}
}