This commit is contained in:
parent
0c0f08b350
commit
171fbf1927
9 changed files with 2589 additions and 37 deletions
|
|
@ -324,13 +324,9 @@ describe('laminate planning', () => {
|
|||
// 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);
|
||||
expect(Math.abs(signedDistance(phases[i - 1], phases[i + 1]))).toBeGreaterThanOrEqual(
|
||||
s.width,
|
||||
);
|
||||
}
|
||||
// Breaking the old regular pattern must not increase the stock requirement for these rooms.
|
||||
expect(plan.boardCount).toBeLessThanOrEqual(boardBudget);
|
||||
|
|
|
|||
|
|
@ -2,14 +2,16 @@ import { describe, expect, it } from 'vitest';
|
|||
import { plannerCases } from '../benchmarks/cases';
|
||||
import {
|
||||
compareFlooring,
|
||||
compareCurrentFlooring,
|
||||
compareSkirting,
|
||||
flooringMetrics,
|
||||
skirtingMetrics,
|
||||
} from '../benchmarks/metrics';
|
||||
import baseline from '../benchmarks/baseline.json';
|
||||
import hBaseline from '../benchmarks/h-pattern-baseline.json';
|
||||
import { planFlooringOptions } from '../src/lib/flooring';
|
||||
import { planSkirting } from '../src/lib/skirting';
|
||||
import { defaultProject, rectangle } from '../src/lib/defaults';
|
||||
import { defaultProject, fireplace, rectangle } from '../src/lib/defaults';
|
||||
import { buildGeometry, insetPolygon, signedArea } from '../src/lib/geometry';
|
||||
import type { FlooringPlan, Project } from '../src/lib/types';
|
||||
|
||||
|
|
@ -118,8 +120,15 @@ describe('measured optimiser quality', () => {
|
|||
const random = flooringMetrics(options.random, project.flooring);
|
||||
const before = baseline.find((row) => row.name === name)!;
|
||||
expect(compareFlooring(cuts, before.flooring)).toBeLessThanOrEqual(0);
|
||||
expect(compareFlooring(cuts, random)).toBeLessThanOrEqual(0);
|
||||
expect(compareFlooring(random, cuts, true)).toBeLessThanOrEqual(0);
|
||||
expect(compareCurrentFlooring(cuts, random)).toBeLessThanOrEqual(0);
|
||||
expect(compareCurrentFlooring(random, cuts, true)).toBeLessThanOrEqual(0);
|
||||
const previousAppearance = hBaseline.find((row) => row.name === name)!;
|
||||
expect(compareCurrentFlooring(random, previousAppearance.random, true)).toBeLessThanOrEqual(
|
||||
0,
|
||||
);
|
||||
expect(random.nearH).toBeLessThanOrEqual(previousAppearance.random.nearH);
|
||||
// Only this fixture's 600 mm minimum pieces force alternating starts.
|
||||
if (name !== 'forced-alternation') expect(random.nearH).toBe(0);
|
||||
validateFlooring(options.cuts, project);
|
||||
if (options.random !== options.cuts) validateFlooring(options.random, project);
|
||||
expect(compareSkirting(skirt, before.skirting)).toBeLessThanOrEqual(0);
|
||||
|
|
@ -129,17 +138,20 @@ describe('measured optimiser quality', () => {
|
|||
);
|
||||
|
||||
it('retains the measured improvements across the complete fixed corpus', () => {
|
||||
const totals = { cuts: 0, randomCuts: 0, pattern: 0, skirtingCuts: 0 };
|
||||
const totals = { cuts: 0, randomCuts: 0, pattern: 0, nearH: 0, skirtingCuts: 0 };
|
||||
for (const c of cases) {
|
||||
const { options, skirt } = resultFor(c);
|
||||
totals.cuts += options.cuts.cuts;
|
||||
totals.randomCuts += options.random.cuts;
|
||||
totals.pattern += flooringMetrics(options.random, c.project.flooring).patternPenalty;
|
||||
totals.nearH += flooringMetrics(options.random, c.project.flooring).nearH;
|
||||
totals.skirtingCuts += skirt.cuts;
|
||||
}
|
||||
expect(totals.cuts).toBeLessThanOrEqual(1741); // Original: 2177.
|
||||
expect(totals.randomCuts).toBeLessThanOrEqual(1994);
|
||||
expect(totals.pattern).toBeLessThanOrEqual(113); // Original: 265.
|
||||
// Broader H avoidance costs more cuts, while still beating the original 2177 passes.
|
||||
expect(totals.randomCuts).toBeLessThanOrEqual(2113);
|
||||
expect(totals.nearH).toBeLessThanOrEqual(6); // Before the visual correction: 557.
|
||||
expect(totals.pattern).toBeLessThanOrEqual(346); // Retain the separate legacy diagnostic.
|
||||
expect(totals.skirtingCuts).toBeLessThanOrEqual(1436); // Original: 1447.
|
||||
});
|
||||
|
||||
|
|
@ -154,4 +166,18 @@ describe('measured optimiser quality', () => {
|
|||
expect(plan.cuts).toBe(750);
|
||||
expect(plan.coveredArea).toBe(4500 * 95000);
|
||||
});
|
||||
|
||||
it.each(Array.from({ length: 10 }, (_, i) => i + 1))(
|
||||
'avoids broad H joints with independent room seed %i',
|
||||
(seed) => {
|
||||
const project = defaultProject();
|
||||
project.rooms = [
|
||||
seed % 2 ? rectangle(`holdout-${seed}`) : fireplace(`holdout-${seed}`, 'Fireplace'),
|
||||
];
|
||||
const plan = planFlooringOptions(project.rooms, project.flooring, project.tolerance).random;
|
||||
expect(flooringMetrics(plan, project.flooring).nearH).toBe(0);
|
||||
expect(plan.boardCount).toBeLessThanOrEqual(seed % 2 ? 76 : 74);
|
||||
validateFlooring(plan, project);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue