def resolve_ball_wall_collision(ball: PoolBall, wall: Direction):
    """
    Sets the new velocity for this ball after it has collided with a wall.
    *Assumes wall is in one of 4 directions: N, E, S, or W*

    :param ball: pool ball
    :param wall: which wall (N, E, S, W)
    """

    if wall == Direction.NORTH or wall == Direction.SOUTH:
        ball.vel = Vector(ball.vel.x, -ball.vel.y)  # Reverse y-direction
    else:  # EAST or WEST
        ball.vel = Vector(-ball.vel.x, ball.vel.y)  # Reverse x-direction
def resolve_ball_ball_collision(a: PoolBall, b: PoolBall):
    """
    Sets new velocity vectors after a ball-ball collision.

    :param a: ball A
    :param b: ball B
    """

    # Taken from https://en.wikipedia.org/wiki/Elastic_collision#Two-dimensional_collision_with_two_moving_objects

    a_vel_new = a.vel - (2 * b.mass) / (a.mass + b.mass) * (
        (a.vel - b.vel).dot_product(a.pos - b.pos)
    ) / get_distance(a.pos - b.pos)**2 * (a.pos - b.pos)
    b_vel_new = b.vel - (2 * a.mass) / (a.mass + b.mass) * (
        (b.vel - a.vel).dot_product(b.pos - a.pos)
    ) / get_distance(b.pos - a.pos)**2 * (b.pos - a.pos)

    a.vel, b.vel = a_vel_new, b_vel_new