def get_closest_point(x0, y0, Ax, Ay, Bx, By):
    """
    Return the point on the line segment defined by (Ax, Ay) and (Bx, By)
    closest to (x0, y0).
    """

    if (Ax, Ay) == (Bx, By): # There is no line segment
        return Ax, Ay
    elif Ay == By: # The line is horizontal
        if Bx < Ax:
            Ax, Ay, Bx, By = Bx, By, Ax, Ay
        if x0 <= Ax:
            return Ax, Ay
        elif x0 >= Bx:
            return Bx, By
        return x0, Ay
    elif Ax == Bx: # The line is vertical
        if By < Ay:
            Ax, Ay, Bx, By = Bx, By, Ax, Ay
        if y0 < Ay:
            return Ax, Ay
        elif y0 > By:
            return Bx, By
        return Ax, y0
    else: # The line is some sort of diagonal
        # http://stackoverflow.com/a/5205747/4718769
        if Bx < Ax:
            Ax, Ay, Bx, By = Bx, By, Ax, Ay

        aTop = Ay > By
        m = -(Bx - Ax) / (By - Ay)

        f = (x0 - Ax) * m + Ay
        if aTop and y0 > f or not aTop and y0 < f:
            return (Ax, Ay)

        g = (x0 - Bx) * m + By
        if aTop and y0 < g or not aTop and y0 > g:
            return (Bx, By)

        # http://stackoverflow.com/a/5205909/4718769
        m1 = (By - Ay) / (Bx - Ax)
        m2 = -1 / m1
        x3 = (m1 * Ax - m2 * x0 + y0 - Ay) / (m1 - m2)
        y3 = m2 * (x3 - x0) + y0
        return (x3, y3)