UNPKG

bump-ts

Version:

![version](https://img.shields.io/npm/v/bump-ts) ![maintenance](https://img.shields.io/maintenance/yes/2021) ![open-issues](https://img.shields.io/github/issues-raw/hood/bump.ts)

85 lines (69 loc) 2.5 kB
import { IRect } from '.'; export function grid_toWorld( cellSize: number, cx: number, cy: number ): [number, number] { return [(cx - 1) * cellSize, (cy - 1) * cellSize]; } export function grid_toCell( cellSize: number, x: number, y: number ): [number, number] { return [Math.floor(x / cellSize) + 1, Math.floor(y / cellSize) + 1]; } //grid_traverse * functions are based on "A Fast Voxel Traversal Algorithm for Ray Tracing", //by John Amanides and Andrew Woo - http://www.cse.yorku.ca/~amana/research/grid.pdf //It has been modified to include both cells when the ray "touches a grid corner", //and with a different exit condition export function grid_traverse_initStep( cellSize: number, ct: number, t1: number, t2: number ): [number, number, number] { const v: number = t2 - t1; if (v > 0) return [1, cellSize / v, ((ct + v) * cellSize - t1) / v]; else if (v < 0) return [-1, -cellSize / v, ((ct + v - 1) * cellSize - t1) / v]; else return [0, Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]; } export function grid_traverse( cellSize: number, x1: number, y1: number, x2: number, y2: number, traverseFunction: (cx: number, cy: number) => void ): void { const [cx1, cy1] = grid_toCell(cellSize, x1, y1); const [cx2, cy2] = grid_toCell(cellSize, x2, y2); let [stepX, dx, tx] = grid_traverse_initStep(cellSize, cx1, x1, x2); let [stepY, dy, ty] = grid_traverse_initStep(cellSize, cy1, y1, y2); let [cx, cy] = [cx1, cy1]; traverseFunction(cx, cy); // The default implementation had an infinite loop problem when // approaching the last cell in some occassions. We finish iterating // when we are *next* to the last cell. do { if (tx < ty) { [tx, cx] = [tx + dx, cx + stepX]; traverseFunction(cx, cy); } else { // Addition: include both cells when going through corners if (tx == ty) traverseFunction(cx + stepX, cy); ty = ty + dy; cy = cy + stepY; traverseFunction(cx, cy); } } while (Math.abs(cx - cx2) + Math.abs(cy - cy2) > 1); //If we have not arrived to the last cell, use it if (cx != cx2 || cy != cy2) traverseFunction(cx2, cy2); } export function grid_toCellRect(cellSize: number, rect: IRect): IRect { let [cx, cy] = grid_toCell(cellSize, rect.x, rect.y); const cr: number = Math.ceil((rect.x + rect.w) / cellSize); const cb: number = Math.ceil((rect.y + rect.h) / cellSize); return { x: cx, y: cy, w: cr - cx + 1, h: cb - cy + 1 }; }