fix(capture): rotate length-axis rectangle and scale from mask span
Length axis keeps the approved mask, replaces Flip 180 with a ± angle slider, and sets scale from wood span along the approved direction rather than bbox.longSidePx. Widths still sample every 6 in perpendicular to that axis.
This commit is contained in:
@@ -92,3 +92,39 @@ export function minAreaRect(bitset: Uint8Array, w: number, h: number): BBox | nu
|
||||
const angleDeg = ((Math.atan2(lv, lu) * 180) / Math.PI + 180) % 180;
|
||||
return { corners, longSidePx: halfL * 2, angleDeg };
|
||||
}
|
||||
|
||||
// Rotate the long side to a new angle, keeping center and half-extents.
|
||||
// Corners are rebuilt in minAreaRect order so corners[3] → corners[0] stays the
|
||||
// long side (the axis arrow direction).
|
||||
export function orientedRect(prev: BBox, angleDeg: number): BBox {
|
||||
const a = ((angleDeg % 180) + 180) % 180;
|
||||
const halfL = prev.longSidePx / 2;
|
||||
const halfS = Math.hypot(prev.corners[0][0] - prev.corners[1][0], prev.corners[0][1] - prev.corners[1][1]) / 2;
|
||||
// corners[i] is a corner point: average of all four = center
|
||||
const cx = (prev.corners[0][0] + prev.corners[1][0] + prev.corners[2][0] + prev.corners[3][0]) / 4;
|
||||
const cy = (prev.corners[0][1] + prev.corners[1][1] + prev.corners[2][1] + prev.corners[3][1]) / 4;
|
||||
const r = (a * Math.PI) / 180;
|
||||
const lu = Math.cos(r), lv = Math.sin(r);
|
||||
const su = -lv, sv = lu;
|
||||
const corners: [number, number][] = [];
|
||||
for (const [aSign, bSign] of [[1, 1], [1, -1], [-1, -1], [-1, 1]] as const) {
|
||||
corners.push([cx + aSign * halfL * lu + bSign * halfS * su, cy + aSign * halfL * lv + bSign * halfS * sv]);
|
||||
}
|
||||
return { corners, longSidePx: prev.longSidePx, angleDeg: a };
|
||||
}
|
||||
|
||||
// Project every slab pixel onto the unit vector (ux, uy); return max − min
|
||||
// extent in px. 0 when the mask is empty.
|
||||
export function maskSpanAlong(bitset: Uint8Array, w: number, h: number, ux: number, uy: number): number {
|
||||
let min = Infinity, max = -Infinity;
|
||||
for (let y = 0; y < h; y++) {
|
||||
const row = y * w;
|
||||
for (let x = 0; x < w; x++) {
|
||||
if (!bitset[row + x]) continue;
|
||||
const p = x * ux + y * uy;
|
||||
if (p < min) min = p;
|
||||
if (p > max) max = p;
|
||||
}
|
||||
}
|
||||
return max < min ? 0 : max - min;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user