add guillotine_bssf_sas
This commit is contained in:
parent
c2994b74bd
commit
9a9a05d1d7
@ -105,3 +105,60 @@ def maxrects_bssf(
|
||||
|
||||
regions = numpy.vstack((regions[~intersects], r_lft, r_bot, r_rgt, r_top))
|
||||
return rect_locs, rejected_inds
|
||||
|
||||
|
||||
def guillotine_bssf_sas(rect_sizes: numpy.ndarray,
|
||||
regions: numpy.ndarray,
|
||||
presort: bool = True,
|
||||
allow_rejects: bool = True,
|
||||
) -> Tuple[numpy.ndarray, Set[int]]:
|
||||
"""
|
||||
sizes should be Nx2
|
||||
regions should be Mx4 (xmin, ymin, xmax, ymax)
|
||||
#TODO: test me!
|
||||
"""
|
||||
rect_sizes = numpy.array(rect_sizes)
|
||||
rect_locs = numpy.zeros_like(rect_sizes)
|
||||
rejected_inds = set()
|
||||
|
||||
if presort:
|
||||
rotated_sizes = numpy.sort(rect_sizes, axis=0) # shortest side first
|
||||
rect_order = numpy.lexsort(rotated_sizes.T)[::-1] # Descending shortest side
|
||||
rect_sizes = rect_sizes[rect_order]
|
||||
|
||||
for rect_ind, rect_size in enumerate(rect_sizes):
|
||||
''' Place the rect '''
|
||||
# Best short-side fit (bssf) to pick a region
|
||||
bssf_scores = ((regions[:, 2:] - regions[:, :2]) - rect_size).min(axis=1).astype(float)
|
||||
bssf_scores[bssf_scores < 0] = numpy.inf # doesn't fit!
|
||||
rr = bssf_scores.argmin()
|
||||
if numpy.isinf(bssf_scores[rr]):
|
||||
if allow_rejects:
|
||||
rejected_inds.add(rect_ind)
|
||||
continue
|
||||
else:
|
||||
raise MasqueError(f'Failed to find a suitable location for rectangle {rect_ind}')
|
||||
|
||||
# Read out location
|
||||
loc = regions[rr, :2]
|
||||
rect_locs[rect_ind] = loc
|
||||
|
||||
region_size = regions[rr, 2:] - loc
|
||||
split_horiz = region_size[0] < region_size[1]
|
||||
|
||||
new_region0 = regions[rr].copy()
|
||||
new_region1 = new_region0.copy()
|
||||
split_vert = loc + rect_size
|
||||
if split_horiz:
|
||||
new_region0[2] = split_vert[0]
|
||||
new_region0[1] = split_vert[1]
|
||||
new_region1[0] = split_vert[0]
|
||||
else:
|
||||
new_region0[3] = split_vert[1]
|
||||
new_region0[0] = split_vert[0]
|
||||
new_region1[1] = split_vert[1]
|
||||
|
||||
regions = numpy.vstack((regions[:rr], regions[rr + 1:],
|
||||
new_region0, new_region1))
|
||||
|
||||
return rect_locs, rejected_inds
|
||||
|
Loading…
Reference in New Issue
Block a user