def get_minimum_bounding_box_bv(points, voxel_size, bound, downsample=8, margin=1.6):
    x_vsize = voxel_size[0]
    y_vsize = voxel_size[1]
    max_x = points[:, 0].max()
    max_y = points[:, 1].max()
    min_x = points[:, 0].min()
    min_y = points[:, 1].min()
    max_x = (np.floor(((max_x / (x_vsize * downsample)) + 1)) * (x_vsize * downsample))
    max_y = (np.floor(((max_y / (y_vsize * downsample)) + 1)) * (y_vsize * downsample))
    min_x = (np.floor((min_x / (x_vsize * downsample))) * (x_vsize * downsample))
    min_y = (np.floor((min_y / (y_vsize * downsample))) * (y_vsize * downsample))
    max_x = np.minimum((max_x + margin), bound[2])
    max_y = np.minimum((max_y + margin), bound[3])
    min_x = np.maximum((min_x - margin), bound[0])
    min_y = np.maximum((min_y - margin), bound[1])
    return np.array([min_x, min_y, max_x, max_y])
def get_minimum_bounding_box_bv(points, voxel_size, bound, downsample=8, margin=1.6):
    x_vsize = voxel_size[0]
    y_vsize = voxel_size[1]
    max_x = points[:, 0].max()
    max_y = points[:, 1].max()
    min_x = points[:, 0].min()
    min_y = points[:, 1].min()
    max_x = (np.floor(((max_x / (x_vsize * downsample)) + 1)) * (x_vsize * downsample))
    max_y = (np.floor(((max_y / (y_vsize * downsample)) + 1)) * (y_vsize * downsample))
    min_x = (np.floor((min_x / (x_vsize * downsample))) * (x_vsize * downsample))
    min_y = (np.floor((min_y / (y_vsize * downsample))) * (y_vsize * downsample))
    max_x = np.minimum((max_x + margin), bound[2])
    max_y = np.minimum((max_y + margin), bound[3])
    min_x = np.maximum((min_x - margin), bound[0])
    min_y = np.maximum((min_y - margin), bound[1])
    return np.array([min_x, min_y, max_x, max_y])