Skip to content

Commit

Permalink
feat: add cuts to optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
kacperwyczawski committed Feb 20, 2024
1 parent a92ae3f commit 64b4bf2
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 40 deletions.
10 changes: 9 additions & 1 deletion src/components/OptimizationResults.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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"
></rect>
<line
v-for="cut in optimizedSheet.cuts"
:x1="cut.x"
:y1="cut.y"
:x2="cut.direction === 'horizontal' ? cut.x + cut.length : cut.x"
:y2="cut.direction === 'horizontal' ? cut.y : cut.y + cut.length"
class="stroke-neutral"
></line>
</svg>
</div>
</template>
12 changes: 12 additions & 0 deletions src/core/cut.ts
Original file line number Diff line number Diff line change
@@ -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";
};
112 changes: 74 additions & 38 deletions src/core/optimize.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Cut } from "./cut";
import type { OptimizedSheet } from "./optimizedSheet";
import type { Panel } from "./panel";
import type { Sheet } from "./sheet";
Expand All @@ -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[] = [];
Expand All @@ -39,6 +40,7 @@ export function optimize(
const newSheet: OptimizedSheet = {
sheet: { ...sheet },
panels: [],
cuts: [],
};
optimizedSheets.push(newSheet);
fit = {
Expand All @@ -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;
}
4 changes: 3 additions & 1 deletion src/core/optimizedSheet.ts
Original file line number Diff line number Diff line change
@@ -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[];
};

0 comments on commit 64b4bf2

Please sign in to comment.