From 64b4bf2bdb7884245efaaaa517e38b0e6adb2658 Mon Sep 17 00:00:00 2001 From: Kacper Wyczawski Date: Tue, 20 Feb 2024 20:17:50 +0100 Subject: [PATCH] feat: add cuts to optimization --- src/components/OptimizationResults.vue | 10 ++- src/core/cut.ts | 12 +++ src/core/optimize.ts | 112 ++++++++++++++++--------- src/core/optimizedSheet.ts | 4 +- 4 files changed, 98 insertions(+), 40 deletions(-) create mode 100644 src/core/cut.ts diff --git a/src/components/OptimizationResults.vue b/src/components/OptimizationResults.vue index 3a0d8ff..3b08915 100644 --- a/src/components/OptimizationResults.vue +++ b/src/components/OptimizationResults.vue @@ -18,8 +18,16 @@ defineProps<{ :y="optimizedPanel.y" :width="optimizedPanel.panel.length" :height="optimizedPanel.panel.width" - class="stroke-neutral fill-base-200" + class="fill-base-200" > + diff --git a/src/core/cut.ts b/src/core/cut.ts new file mode 100644 index 0000000..9ade2ef --- /dev/null +++ b/src/core/cut.ts @@ -0,0 +1,12 @@ +/** + * Represents a single cut + * @property {number} x - In mm, calculated from the left edge of the sheet to the center of the cut, if it's a vertical cut + * @property {number} y - In mm, calculated from the top edge of the sheet to the center of the cut, if it's a horizontal cut + * @property {number} length - In mm + */ +export type Cut = { + x: number; + y: number; + length: number; + direction: "vertical" | "horizontal"; +}; diff --git a/src/core/optimize.ts b/src/core/optimize.ts index d5d1fa8..1486df6 100644 --- a/src/core/optimize.ts +++ b/src/core/optimize.ts @@ -1,3 +1,4 @@ +import type { Cut } from "./cut"; import type { OptimizedSheet } from "./optimizedSheet"; import type { Panel } from "./panel"; import type { Sheet } from "./sheet"; @@ -14,7 +15,7 @@ export function optimize( sheet: Sheet, panels: Panel[], bladeThickness: number, -) { +): OptimizedSheet[] { // TODO: fail if there is a panel bigger than the sheet console.info("Optimization started"); let freeRectangles: FreeSpace[] = []; @@ -39,6 +40,7 @@ export function optimize( const newSheet: OptimizedSheet = { sheet: { ...sheet }, panels: [], + cuts: [], }; optimizedSheets.push(newSheet); fit = { @@ -58,48 +60,82 @@ export function optimize( x: fit.x, y: fit.y, }); - - // add new free rectangles - freeRectangles.push( - ...generateNewFreeRectangles(fit, panel, bladeThickness), + console.debug( + `Adding panel ${panel.length}x${panel.width} to sheet, at ${fit.x},${fit.y}`, ); - } - return optimizedSheets; -} + // generate new cuts and free rectangles if needed + if (fit.length === panel.length && fit.width === panel.width) { + // panel fits perfectly 👌 + // so no new free rectangles + // TODO: Check if cuts are needed + } else if (fit.length === panel.length) { + const newFreeRectangle = { ...fit }; + newFreeRectangle.y = fit.y + panel.width + bladeThickness; + newFreeRectangle.width = fit.width - panel.width; + freeRectangles.push(newFreeRectangle); -function generateNewFreeRectangles( - fit: FreeSpace, - currentPanel: Panel, - bladeThickness: number, -): FreeSpace[] { - if (fit.length === currentPanel.length && fit.width === currentPanel.width) { - // panel fits perfectly 👌 - // so no new free rectangles - return []; - } else if (fit.length === currentPanel.length) { - const result = { ...fit }; - result.y = fit.y + currentPanel.width + bladeThickness; - result.width = fit.width - currentPanel.width; - return [result]; - } else if (fit.width === currentPanel.width) { - const result = { ...fit }; - result.x = fit.x + currentPanel.length + bladeThickness; - result.length = fit.length - currentPanel.length; - return [result]; - } else { - // TODO: maybe change preference based on length/width ratio of sheet - // prefer horizontal split/cut + const newCut: Cut = { + x: fit.x, + y: fit.y + panel.width, + length: fit.length, + direction: "horizontal", + }; + fit.sheet.cuts.push(newCut); + } else if (fit.width === panel.width) { + const newFreeRectangle = { ...fit }; + newFreeRectangle.x = fit.x + panel.length + bladeThickness; + newFreeRectangle.length = fit.length - panel.length; + freeRectangles.push(newFreeRectangle); + + const newCut: Cut = { + x: fit.x + panel.length, + y: fit.y, + length: fit.width, + direction: "vertical", + }; + fit.sheet.cuts.push(newCut); + } else { + // panel is smaller than fit, so we need to create two new free rectangles and two new cuts - const panelBelow = { ...fit }; - panelBelow.y = fit.y + currentPanel.width + bladeThickness; - panelBelow.width = fit.width - currentPanel.width - bladeThickness; + // TODO: maybe change preference based on length/width ratio of sheet - const panelToTheRight = { ...fit }; - panelToTheRight.x = fit.x + currentPanel.length + bladeThickness; - panelToTheRight.length = fit.length - currentPanel.length - bladeThickness; - panelToTheRight.width = currentPanel.width + bladeThickness; + // for now prefer horizontal cut, like this: + // +---+---+ + // | N | | <- N = new panel + // +---+---+ + // | | + // +---+---+ - return [panelBelow, panelToTheRight]; + const newFreeRectangleBelow = { ...fit }; + newFreeRectangleBelow.y = fit.y + panel.width + bladeThickness; + newFreeRectangleBelow.width = fit.width - panel.width - bladeThickness; + freeRectangles.push(newFreeRectangleBelow); + + const newFreeRectangleToTheRight = { ...fit }; + newFreeRectangleToTheRight.x = fit.x + panel.length + bladeThickness; + newFreeRectangleToTheRight.length = + fit.length - panel.length - bladeThickness; + newFreeRectangleToTheRight.width = panel.width + bladeThickness; + freeRectangles.push(newFreeRectangleToTheRight); + + const newHorizontalCut: Cut = { + x: fit.x, + y: fit.y + panel.width, + length: fit.length, + direction: "horizontal", + }; + fit.sheet.cuts.push(newHorizontalCut); + + const newVerticalCut: Cut = { + x: fit.x + panel.length, + y: fit.y, + length: panel.width + bladeThickness / 2, + direction: "vertical", + }; + fit.sheet.cuts.push(newVerticalCut); + } } + + return optimizedSheets; } diff --git a/src/core/optimizedSheet.ts b/src/core/optimizedSheet.ts index 37ddb9a..4263a97 100644 --- a/src/core/optimizedSheet.ts +++ b/src/core/optimizedSheet.ts @@ -1,7 +1,9 @@ +import type { Cut } from "./cut"; import type { OptimizedPanel } from "./optimizedPanel"; import type { Sheet } from "./sheet"; export type OptimizedSheet = { - panels: OptimizedPanel[]; sheet: Sheet; + panels: OptimizedPanel[]; + cuts: Cut[]; };