class GridField {
constructor(width, height, cellSize) {
Object.assign(this, { width, height, cellSize });
this.nx = Math.round(width / cellSize);
this.ny = Math.round(height / cellSize);
this.grid = d3
.range(this.nx)
.map((ix) => d3.range(this.ny).map((iy) => defaultAngle));
}
clone() {
let copy = new GridField(this.width, this.height, this.cellSize);
copy.grid = [...this.grid.map((row) => [...row])];
return copy;
}
getCell(ix, iy) {
ix = Math.min(this.nx - 1, Math.max(0, ix));
iy = Math.min(this.ny - 1, Math.max(0, iy));
return this.grid[ix][iy];
}
setCell(ix, iy, angle) {
if (ix < this.nx && ix >= 0 && iy < this.ny && iy >= 0)
this.grid[ix][iy] = angle;
}
getCellIndex(x, y) {
return [~~(x / this.cellSize), ~~(y / this.cellSize)];
}
getField(x, y) {
let [ix, iy] = this.getCellIndex(x, y);
let alphax = (x % this.cellSize) / this.cellSize;
let alphay = (y % this.cellSize) / this.cellSize;
return angleLerp(
angleLerp(this.getCell(ix, iy), this.getCell(ix + 1, iy), alphax),
angleLerp(this.getCell(ix, iy + 1), this.getCell(ix + 1, iy + 1), alphax),
alphay
);
}
draw(ctx) {
ctx.beginPath();
for (let i = 0; i < this.nx; i++) {
for (let j = 0; j < this.ny; j++) {
drawArrow(
ctx,
(i + 0.5) * this.cellSize,
(j + 0.5) * this.cellSize,
this.getCell(i, j),
cellSize * 0.8
);
}
}
ctx.stroke();
}
}