def compute_location_asymmetry(objects, centroid):
    """Compute location asymmetry based on the described method."""
    num_objects = len(objects)

    P = np.zeros((num_objects, 2))
    for i, obj in enumerate(objects):
        P[i] = np.array([obj.location.x, obj.location.y]) - centroid
    # print(P)

    # 2. Rotate all P_i so that P_1 is aligned with the x axis
    angle_p1 = np.arctan2(P[0][1], P[0][0])
    for i in range(num_objects):
        P[i] = rotate_vector(P[i], -angle_p1)

    # 3. Normalize P_i by dividing by max norm
    max_norm = max(np.linalg.norm(P, axis=1))
    P /= max_norm
    # print(P)

    # 4. Compute Q as the average of the rotated P_i vectors
    Q = np.zeros(2)
    for i in range(num_objects):
        rotated_p = rotate_vector(P[i], -i * 2 * np.pi / num_objects)
        #        print("rot", P[i], rotated_p)
        Q += rotated_p
    Q /= num_objects

    # 5. and 6. Compute Q_i and find the MSD between Q_i and P_i
    total_msd = 0
    for i in range(num_objects):
        Q_i = rotate_vector(Q, i * 2 * np.pi / num_objects)
        #        print("rot2", Q_i, P[i])
        msd = np.linalg.norm(Q_i - P[i]) ** 2
        total_msd += msd

    return total_msd / num_objects
Compute location asymmetry based on the described method.
infinigen/core/constraints/evaluator/node_impl/symmetry.py