thi-ng/umbrella

View on GitHub
packages/geom-sdf/src/sample.ts

Summary

Maintainability
A
45 mins
Test Coverage
import type { Fn, NumericArray } from "@thi.ng/api";
import { assert } from "@thi.ng/errors/assert";
import type { AABBLike } from "@thi.ng/geom";
import type { ReadonlyVec, Vec } from "@thi.ng/vectors";
import type { SDFn } from "./api.js";

/**
 * Samples and discretizes the given SDF within the given bounding rect and
 * resolution. The optional `domain` fn can be used to apply modifiers to each
 * sample position. If `buf` is provided, writes results into it, else creates a
 * new buffer automatically. Returns buffer.
 *
 * @param sdf
 * @param bounds
 * @param res
 * @param domain
 * @param buf
 */
export const sample2d = (
    sdf: SDFn,
    { pos: [px, py], size: [width, height] }: AABBLike,
    [resX, resY]: ReadonlyVec,
    domain?: Fn<ReadonlyVec, Vec>,
    buf?: NumericArray
) => {
    if (buf) {
        assert(buf.length >= resX * resY, "insufficient buffer size");
    } else {
        buf = new Float32Array(resX * resY);
    }
    const dx = width / (resX - 1);
    const dy = height / (resY - 1);
    const p = [0, 0];
    for (let y = 0, i = 0; y < resY; y++) {
        p[1] = py + y * dy;
        for (let x = 0; x < resX; x++, i++) {
            p[0] = px + x * dx;
            buf[i] = sdf(domain ? domain(p) : p);
        }
    }
    return buf;
};