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:])]