def liang_barsky(bottom, top, left, right, y0, x0, y1, x1):
    """ Compute the intersection between a rectangle and a line segment.

        rect is sepcified by (bottom, top, left, right)
        line segment specified by (y0, x0), (y1, x1)

        If no intersection, returns None.

        Otherwise, returns (r, s) where (y0, x0) + r * (y1 - y0, x1 - x0) is the location of the "ingoing"
        intersection, and (y0, x0) + s * (y1 - y0, x1 - x0) is the location of the "outgoing" intersection.
        It will always hold that 0 <= r <= s <= 1. If the line segment starts inside the rectangle then r = 0;
        and if it stops inside the rectangle then s = 1.

    """
    assert bottom < top
    assert left < right

    dx = x1 - x0
    dy = y1 - y0

    checks = ((-dx, -(left - x0)),
              (dx, right - x0),
              (-dy, -(bottom - y0)),
              (dy, top - y0))

    out_in = [0]
    in_out = [1]

    for p, q in checks:
        if p == 0 and q < 0:
            return None

        if p != 0:
            target_list = out_in if p < 0 else in_out
            target_list.append(q / p)

    _out_in = max(out_in)
    _in_out = min(in_out)

    if _out_in < _in_out:
        return _out_in, _in_out
    else:
        return None