def _further_randomize()

in mujoco_worldgen/util/placement.py [0:0]


def _further_randomize(random_state, boxes, a, b, xy):
    # Determines how much positions can be shifted.
    slack = np.zeros((2, a.shape[1]))
    slack[0, :] = -np.inf
    slack[1, :] = np.inf
    # a * xy - b > sol_slack
    # if a[i][j] == 1 then xy[j] can be as small as -slack / np.sum(abs(a[i]))
    # if a[i][j] == -1 then xy[j] can be as big as slack / np.sum(abs(a[i]))
    # np.sum(abs(a[i]))
    sol_slack = np.matmul(a, xy) - b
    for i in range(a.shape[0]):
        row = np.sum(np.abs(a[i]))
        for j in range(a.shape[1]):
            if np.abs(a[i][j] - 1.) < 1e-4:
                slack[0][j] = min(
                    max(sol_slack[i], -slack[0][j]) / row, 0)
            elif np.abs(a[i][j] + 1.) < 1e-4:
                slack[1][j] = max(
                    min(sol_slack[i], slack[1][j]) / row, 0)
    assert((slack[0][:] <= slack[1][:]).all())
    dim = xy.shape[0] // 2
    for i in range(xy.shape[0]):
        if boxes[i % dim]["placement_xy"] is None:
            xy[i] += random_state.uniform(slack[0][i], slack[1][i])
    return [(a, b) for a, b in zip(xy[:dim], xy[dim:])]