Added Configuration from Item and Plate
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
package layout
|
||||
|
||||
import (
|
||||
"printer.backend/internal/model"
|
||||
)
|
||||
|
||||
// Footprint returns the physical width and height one item occupies on the plate (mm).
|
||||
// Includes bleed on all sides and the item's margin as a safe zone.
|
||||
func Footprint(spec model.ItemSpec) (width, height float64) {
|
||||
w := spec.SizeMM + 2*spec.BleedMM + 2*spec.MarginMM
|
||||
return w, w
|
||||
}
|
||||
|
||||
// CellPitch returns width and height of one grid cell (footprint + spacing between items).
|
||||
func CellPitch(spec model.ItemSpec, spacingMM float64) (width, height float64) {
|
||||
fw, fh := Footprint(spec)
|
||||
return fw + spacingMM, fh + spacingMM
|
||||
}
|
||||
|
||||
// Pack computes the maximum grid of items that fit on the plate.
|
||||
func Pack(plate model.Plate, spec model.ItemSpec, spacingMM float64) model.LayoutPreview {
|
||||
pw := plate.PrintableWidth()
|
||||
ph := plate.PrintableHeight()
|
||||
fw, fh := Footprint(spec)
|
||||
cw, ch := CellPitch(spec, spacingMM)
|
||||
|
||||
cols, rows := gridCount(pw, ph, cw, ch)
|
||||
count := cols * rows
|
||||
|
||||
ox := plate.MarginLeft
|
||||
oy := plate.MarginTop
|
||||
|
||||
positions := make([]model.LayoutPosition, 0, count)
|
||||
for row := 0; row < rows; row++ {
|
||||
for col := 0; col < cols; col++ {
|
||||
positions = append(positions, model.LayoutPosition{
|
||||
XMM: ox + float64(col)*cw,
|
||||
YMM: oy + float64(row)*ch,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return model.LayoutPreview{
|
||||
PlateWidthMM: plate.WidthMM,
|
||||
PlateHeightMM: plate.HeightMM,
|
||||
PrintableXMM: ox,
|
||||
PrintableYMM: oy,
|
||||
PrintableWMM: pw,
|
||||
PrintableHMM: ph,
|
||||
CellWidthMM: cw,
|
||||
CellHeightMM: ch,
|
||||
FootprintWMM: fw,
|
||||
FootprintHMM: fh,
|
||||
SpacingMM: spacingMM,
|
||||
Columns: cols,
|
||||
Rows: rows,
|
||||
Count: count,
|
||||
Positions: positions,
|
||||
}
|
||||
}
|
||||
|
||||
func gridCount(printableW, printableH, cellW, cellH float64) (cols, rows int) {
|
||||
if printableW <= 0 || printableH <= 0 || cellW <= 0 || cellH <= 0 {
|
||||
return 0, 0
|
||||
}
|
||||
cols = int(printableW / cellW)
|
||||
rows = int(printableH / cellH)
|
||||
if cols < 0 {
|
||||
cols = 0
|
||||
}
|
||||
if rows < 0 {
|
||||
rows = 0
|
||||
}
|
||||
return cols, rows
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package layout
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"printer.backend/internal/model"
|
||||
)
|
||||
|
||||
func TestPack(t *testing.T) {
|
||||
plate := model.Plate{
|
||||
WidthMM: 300,
|
||||
HeightMM: 400,
|
||||
MarginTop: 10,
|
||||
MarginRight: 10,
|
||||
MarginBottom: 10,
|
||||
MarginLeft: 10,
|
||||
}
|
||||
spec := model.ItemSpec{SizeMM: 80, BleedMM: 2, MarginMM: 5}
|
||||
// footprint = 80+4+10 = 94, cell = 94+2 = 96
|
||||
// printable 280x380 -> cols=2, rows=3 -> 6
|
||||
preview := Pack(plate, spec, 2)
|
||||
if preview.Columns != 2 {
|
||||
t.Fatalf("columns: got %d want 2", preview.Columns)
|
||||
}
|
||||
if preview.Rows != 3 {
|
||||
t.Fatalf("rows: got %d want 3", preview.Rows)
|
||||
}
|
||||
if preview.Count != 6 {
|
||||
t.Fatalf("count: got %d want 6", preview.Count)
|
||||
}
|
||||
if len(preview.Positions) != 6 {
|
||||
t.Fatalf("positions: got %d want 6", len(preview.Positions))
|
||||
}
|
||||
if preview.Positions[0].XMM != 10 || preview.Positions[0].YMM != 10 {
|
||||
t.Fatalf("first position: got (%v,%v)", preview.Positions[0].XMM, preview.Positions[0].YMM)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPackZeroCell(t *testing.T) {
|
||||
plate := model.Plate{WidthMM: 10, HeightMM: 10}
|
||||
spec := model.ItemSpec{SizeMM: 100}
|
||||
preview := Pack(plate, spec, 0)
|
||||
if preview.Count != 0 {
|
||||
t.Fatalf("expected 0 items, got %d", preview.Count)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user