.
This commit is contained in:
parent
d8f2407ddf
commit
9689bfcc18
23 changed files with 1815 additions and 955 deletions
|
|
@ -215,6 +215,78 @@ describe('laminate planning', () => {
|
|||
expectCoverage(a, room(), s.gap);
|
||||
});
|
||||
|
||||
it.each([
|
||||
['rectangle', room(4800, 3600, 'room-1'), 76, 42],
|
||||
['fireplace', fireplace('room-2', 'Fireplace room'), 74, 48],
|
||||
] as const)(
|
||||
'breaks random staircases and near-brick repeats in a common %s',
|
||||
(_, r, boardBudget, cutBudget) => {
|
||||
const s = { ...settings, width: 190, pattern: 'random' as const };
|
||||
const plan = planFlooring([r], s, 1);
|
||||
expect(errors(plan)).toEqual([]);
|
||||
expect(plan).toEqual(planFlooring([r], s, 1));
|
||||
const phases = plan.rows.map((row) => row.offset);
|
||||
const signedDistance = (a: number, b: number) => {
|
||||
let difference = b - a;
|
||||
if (difference >= s.length / 2) difference -= s.length;
|
||||
if (difference < -s.length / 2) difference += s.length;
|
||||
return difference;
|
||||
};
|
||||
const steps = phases.slice(1).map((phase, i) => signedDistance(phases[i], phase));
|
||||
// This case actually crosses the board boundary, so checking raw differences would miss steps.
|
||||
expect(
|
||||
phases.some((phase, i) => i > 0 && Math.abs(phase - phases[i - 1]) > s.length / 2),
|
||||
).toBe(true);
|
||||
for (let i = 1; i < steps.length; i++) {
|
||||
// Similar signed steps across three rows produce a visible staircase, even with small kerf drift.
|
||||
expect(Math.abs(steps[i] - steps[i - 1])).toBeGreaterThan(36);
|
||||
// Returning to almost the same joint line two rows later produces an H/brick repeat.
|
||||
expect(Math.abs(signedDistance(phases[i - 1], phases[i + 1]))).toBeGreaterThan(36);
|
||||
}
|
||||
for (let i = 2; i < steps.length; i++) {
|
||||
expect(
|
||||
steps.slice(i - 2, i + 1).every((step) => step > 0) ||
|
||||
steps.slice(i - 2, i + 1).every((step) => step < 0),
|
||||
).toBe(false);
|
||||
}
|
||||
// Breaking the old regular pattern must not increase the stock requirement for these rooms.
|
||||
expect(plan.boardCount).toBeLessThanOrEqual(boardBudget);
|
||||
expect(plan.cuts).toBeLessThanOrEqual(cutBudget);
|
||||
expect(plan.reusedCount).toBeGreaterThan(0);
|
||||
expect(
|
||||
plan.pieces.every((piece) => piece.length >= s.minLength && piece.width >= s.minWidth),
|
||||
).toBe(true);
|
||||
expectOffsets(plan, s);
|
||||
expectStockFits(plan, s);
|
||||
expectCoverage(plan, r, s.gap);
|
||||
},
|
||||
);
|
||||
|
||||
it('keeps a constrained random layout valid when only alternating starts can fit', () => {
|
||||
const r = room(2420, 1620);
|
||||
const s = { ...settings, pattern: 'random' as const, minLength: 600 };
|
||||
const plan = planFlooring([r], s, 1);
|
||||
expect(errors(plan)).toEqual([]);
|
||||
expect(plan.rows).toHaveLength(8);
|
||||
expect(new Set(plan.rows.map((row) => row.offset))).toEqual(new Set([0, 600]));
|
||||
expect(plan.rows[0].offset).toBe(plan.rows[2].offset);
|
||||
expectOffsets(plan, s);
|
||||
expectStockFits(plan, s);
|
||||
expectCoverage(plan, r, s.gap);
|
||||
});
|
||||
|
||||
it.each([400, 600])(
|
||||
'respects an exact %i mm random offset even when repetition is unavoidable',
|
||||
(offset) => {
|
||||
const s = { ...settings, pattern: 'random' as const, minOffset: offset, maxOffset: offset };
|
||||
const plan = planFlooring([room()], s, 1);
|
||||
expect(errors(plan)).toEqual([]);
|
||||
expect(plan).toEqual(planFlooring([room()], s, 1));
|
||||
expectOffsets(plan, s);
|
||||
expectStockFits(plan, s);
|
||||
},
|
||||
);
|
||||
|
||||
it('rejects impossible brick stagger constraints', () => {
|
||||
const plan = planFlooring([room()], { ...settings, maxOffset: 400 }, 1);
|
||||
expect(plan.boardCount).toBe(0);
|
||||
|
|
|
|||
Loading…
Reference in a new issue