fix(capture): drop first and last 6in from width samples
sampleWidths used floor(L/6)+1 stations from t=0, so tapered tips dominated min/max. Sample only interior stations at 6, 12, … ≤ L−6. When L≤12 there is no interior span: every6In stays empty and min/max/avg stay 0. CAPTURE.md Widths bullet matches. sqft, bdft, scale, and inventory PNG are unchanged.
This commit is contained in:
+1
-1
@@ -94,7 +94,7 @@ On the same photo, keep the approved mask in view and draw the minimum-area boun
|
|||||||
User enters length `L` in inches (1/8 in steps) and thickness (1/8 in steps), then presses Calculate.
|
User enters length `L` in inches (1/8 in steps) and thickness (1/8 in steps), then presses Calculate.
|
||||||
|
|
||||||
- `scale = longest_axis_px / L` where `longest_axis_px` is the mask/wood span along the approved length direction (slab pixels end-to-end on that axis), not the rectangle edge length. The rectangle sets direction only; user-entered `L` is wood end→end along that direction.
|
- `scale = longest_axis_px / L` where `longest_axis_px` is the mask/wood span along the approved length direction (slab pixels end-to-end on that axis), not the rectangle edge length. The rectangle sets direction only; user-entered `L` is wood end→end along that direction.
|
||||||
- Widths: min, max, avg, sampled every 6 in along the approved length axis, perpendicular to it
|
- Widths: min, max, avg from samples taken every 6 in along the approved length axis, perpendicular to it, after dropping the first and last 6 in of the span (bulk widths, not tips). If `L ≤ 12 in` there are no interior stations and all three are 0.
|
||||||
- `sqft = (mask_pixels / scale²) / 144` (2 decimals)
|
- `sqft = (mask_pixels / scale²) / 144` (2 decimals)
|
||||||
- `bdft = sqft × thickness_in` (2 decimals)
|
- `bdft = sqft × thickness_in` (2 decimals)
|
||||||
- Crop: 3:4 portrait, slab centered, 80% fill at the widest and tallest points, transparent background
|
- Crop: 3:4 portrait, slab centered, 80% fill at the widest and tallest points, transparent background
|
||||||
|
|||||||
@@ -39,8 +39,9 @@ function maskAxisSegment(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sampled every 6 in along the wood axis; each sample is a line probe
|
// Interior stations only (6, 12, … ≤ L−6). Tips dominate min/max on tapered
|
||||||
// perpendicular to the axis, width = max run of slab px across the probe.
|
// boards, so the first and last 6 in are excluded. Each sample is a line
|
||||||
|
// probe perpendicular to the axis; width = max run of slab px across it.
|
||||||
function sampleWidths(
|
function sampleWidths(
|
||||||
bitset: Uint8Array, w: number, h: number,
|
bitset: Uint8Array, w: number, h: number,
|
||||||
start: [number, number], ux: number, uy: number,
|
start: [number, number], ux: number, uy: number,
|
||||||
@@ -48,11 +49,10 @@ function sampleWidths(
|
|||||||
): Eighths[] {
|
): Eighths[] {
|
||||||
const px = -uy, py = ux;
|
const px = -uy, py = ux;
|
||||||
const stepPx = 6 * scale;
|
const stepPx = 6 * scale;
|
||||||
const count = Math.max(1, Math.floor(lengthIn / 6) + 1);
|
const lastPx = lengthIn > 12 ? Math.floor((lengthIn - 6) / 6) * 6 * scale : 0;
|
||||||
const out: Eighths[] = [];
|
const out: Eighths[] = [];
|
||||||
const half = Math.max(2, Math.round((w + h) / 4));
|
const half = Math.max(2, Math.round((w + h) / 4));
|
||||||
for (let i = 0; i < count; i++) {
|
for (let t = stepPx; t <= lastPx; t += stepPx) {
|
||||||
const t = i * stepPx;
|
|
||||||
const ox = start[0] + ux * t;
|
const ox = start[0] + ux * t;
|
||||||
const oy = start[1] + uy * t;
|
const oy = start[1] + uy * t;
|
||||||
let minP = Infinity, maxP = -Infinity;
|
let minP = Infinity, maxP = -Infinity;
|
||||||
|
|||||||
Reference in New Issue
Block a user