feat: unified 0 and 90 degree PDF envelope and category descriptors
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* Interpolação bilinear 2D conforme plano técnico (sec. 3.2).
|
||||
*
|
||||
* Dados quatro pontos Q₁₁(x₁,y₁), Q₁₂(x₁,y₂), Q₂₁(x₂,y₁), Q₂₂(x₂,y₂),
|
||||
* estima f(x,y) por:
|
||||
* f ≈ ((x₂-x)(y₂-y)·f₁₁ + (x-x₁)(y₂-y)·f₂₁ + (x₂-x)(y-y₁)·f₁₂ + (x-x₁)(y-y₁)·f₂₂) /
|
||||
* ((x₂-x₁)(y₂-y₁))
|
||||
*
|
||||
* Aceita x fora do intervalo por extrapolação linear (clamp opcional).
|
||||
*/
|
||||
|
||||
export type Grid2D = {
|
||||
xs: readonly number[];
|
||||
ys: readonly number[];
|
||||
values: readonly (readonly number[])[];
|
||||
};
|
||||
|
||||
function findBracket(xs: readonly number[], x: number): [number, number, boolean] {
|
||||
const clamped = Math.max(xs[0], Math.min(x, xs[xs.length - 1]));
|
||||
const extrapolated = clamped !== x;
|
||||
if (xs.length === 1) return [0, 0, extrapolated];
|
||||
if (clamped >= xs[xs.length - 1]) {
|
||||
return [xs.length - 2, xs.length - 1, extrapolated];
|
||||
}
|
||||
for (let i = 0; i < xs.length - 1; i++) {
|
||||
const a = xs[i];
|
||||
const b = xs[i + 1];
|
||||
if (clamped >= a && clamped <= b) {
|
||||
return [i, i + 1, extrapolated];
|
||||
}
|
||||
}
|
||||
return [0, xs.length - 1, extrapolated];
|
||||
}
|
||||
|
||||
export function bilinearInterp(grid: Grid2D, x: number, y: number): number {
|
||||
const { xs, ys, values } = grid;
|
||||
|
||||
const [ix0, ix1] = findBracket(xs, x);
|
||||
const [iy0, iy1] = findBracket(ys, y);
|
||||
|
||||
const x1 = xs[ix0];
|
||||
const x2 = xs[ix1];
|
||||
const y1 = ys[iy0];
|
||||
const y2 = ys[iy1];
|
||||
|
||||
const f11 = values[iy0][ix0];
|
||||
const f21 = values[iy0][ix1];
|
||||
const f12 = values[iy1][ix0];
|
||||
const f22 = values[iy1][ix1];
|
||||
|
||||
const dx = x2 - x1;
|
||||
const dy = y2 - y1;
|
||||
if (dx === 0 || dy === 0) return f11;
|
||||
|
||||
const denom = dx * dy;
|
||||
const num =
|
||||
(x2 - x) * (y2 - y) * f11 +
|
||||
(x - x1) * (y2 - y) * f21 +
|
||||
(x2 - x) * (y - y1) * f12 +
|
||||
(x - x1) * (y - y1) * f22;
|
||||
|
||||
return num / denom;
|
||||
}
|
||||
Reference in New Issue
Block a user