import math
import matplotlib.pyplot as plt
import matplotlib.patches as patches
class Piece:
def __init__(self, id, width, height, quantity):
self.id = id
self.width = width
self.height = height
self.quantity = quantity
self.rotated = False
def get_dim(self):
return (self.height, self.width) if self.rotated else (self.width, self.height)
class Plate:
def __init__(self, id, width, height):
self.id = id
self.width = width - 20
self.height = height - 20
self.pieces = []
self.used_width = 0
self.current_y = 10
def can_place(self, piece, x, y):
w, h = piece.get_dim()
if x + w > self.width + 10: return False
if y + h > self.height + 10: return False
if self.pieces:
last_x, last_w = self.pieces[-1][1], self.pieces[-1][2]
if x < last_x + last_w + 10: return False
return True
def place_piece(self, piece, rotate=False):
if piece.quantity <= 0: return False
piece.rotated = rotate
w, h = piece.get_dim()
if self.used_width + w + 10 > self.width:
self.current_y += h + 10
self.used_width = 0
x = self.used_width + 10
y = self.current_y
if self.can_place(piece, x, y):
self.pieces.append((piece, x, h, y))
self.used_width += w + 10
piece.quantity -= 1
return True
return False
pieces = [ Piece(1, 101.5, 72.5, 5),
Piece(2, 420, 250, 5),
Piece(3, 180, 125, 5),
Piece(4, 157.1, 100, 5),
Piece(5, 388.5, 195, 5),
Piece(6, 778, 126, 5),
Piece(7, 300, 300, 5),
Piece(8, 2323.56, 240.54, 3),
Piece(9, 680, 680, 3),
Piece(10, 130, 80, 5),
]
plates = [ Plate('A', 8000, 3000),
Plate('B', 6000, 2000),
Plate('C', 7000, 2500),
]
sorted_pieces = sorted(pieces, key=lambda p: p.width*p.height, reverse=True)
group_idx = [0, 5, 9]
plate = plates[0]
for p in sorted_pieces[:5]:
while p.quantity > 0:
if not plate.place_piece(p):
if not plate.place_piece(p, rotate=True):
break
plate = plates[1]
for p in sorted_pieces[5:9]:
while p.quantity > 0:
if not plate.place_piece(p):
if not plate.place_piece(p, rotate=True):
break
plate = plates[2]
for p in sorted_pieces[9:] + sorted_pieces[:5][:1]:
while p.quantity > 0:
if not plate.place_piece(p):
if not plate.place_piece(p, rotate=True):
break
def visualize_plate(plate):
fig, ax = plt.subplots(figsize=(8, 4))
ax.set_xlim(0, plate.width + 20)
ax.set_ylim(0, plate.height + 20)
ax.add_patch(patches.Rectangle((10, 10), plate.width, plate.height,
edgecolor='r', fill=False, lw=2))
for data in plate.pieces:
piece, x, w, y = data
ax.add_patch(patches.Rectangle((x, y), w, piece.get_dim()[1],
edgecolor='b', fill=False, lw=1))
ax.text(x+5, y+5, f'ID:{piece.id}', fontsize=6, color='red')
ax.set_title(f"板材{plate.id}排版图({len(set(p.id for p,_,_,_ in plate.pieces))}种工件)")
ax.set_xlabel("宽度(mm)")
ax.set_ylabel("高度(mm)")
ax.grid(True, linestyle='--', alpha=0.5)
plt.show()
for plate in plates:
visualize
_plate(plate)