UNPKG

@thi.ng/rasterize

Version:

Headless 2D shape drawing, filling & rasterization for arbitrary targets/purposes (no canvas required)

55 lines (54 loc) 1.49 kB
import { ensureShader2D } from "./checks.js"; const fillPoly = (grid, pts, val) => { const numP = pts.length; const [width, height] = grid.size; const shader = ensureShader2D(val); let minX = Infinity; let minY = Infinity; let maxX = -Infinity; let maxY = -Infinity; for (let i2 = numP; i2-- > 0; ) { const { 0: x, 1: y } = pts[i2]; minX = Math.min(minX, x); maxX = Math.max(maxX, x); minY = Math.min(minY, y); maxY = Math.max(maxY, y); } minX = Math.max(minX | 0, 0); maxX = Math.min(maxX | 0, width - 1); minY = Math.max(minY | 0, 0); maxY = Math.min(maxY | 0, height - 1); if (minX >= width || maxX < 0 || minY >= height || maxY < 0) return; let i = 0; let k = 0; let j; const isec = []; for (let y = Math.max(0, minY); y <= maxY; y++) { i = k = 0; j = numP - 1; isec.length = 0; for (; i < numP; j = i, i++) { const { 0: pix, 1: piy } = pts[i]; const { 0: pjx, 1: pjy } = pts[j]; if (piy < y && pjy >= y || pjy < y && piy >= y) { isec[k++] = pix + (y - piy) / (pjy - piy) * (pjx - pix) | 0; } } isec.sort((a, b) => a - b); for (i = 0; i < k; i += 2) { let x1 = isec[i]; if (x1 > maxX) break; let x2 = isec[i + 1]; if (x2 > minX) { x1 < minX && (x1 = minX); x2 > maxX && (x2 = maxX); for (let x = x1; x <= x2; x++) { grid.setAtUnsafe(x, y, shader(grid, x, y)); } } } } }; export { fillPoly };