def point_line_seg_distance(p1: tuple, p2: tuple, p: tuple, extend_line: bool = False) -> tuple:
    """
    Compute distance from 2D point p to line segment (p1, p2).
    :param p1: Start point of line in the form (x, y)
    :param p2: End point of line in the form (x, y)
    :param p: Point to compute distance to, in the form (x, y)
    :param extend_line: Should the line be extended as necessary to reduce the distance.
    :return: Tuple(Distance, (x,y) of closest point)
    """
    # Code adapted from https://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment
    assert len(p1) == 2
    assert len(p2) == 2
    assert len(p) == 2

    x1, y1 = p1
    x2, y2 = p2
    x3, y3 = p
    x1, x2, x3, y1, y2, y3 = float(x1), float(x2), float(x3), float(y1), float(y2), float(y3)
    px = x2 - x1
    py = y2 - y1

    norm = px * px + py * py
    if norm == 0:
        dx = x1 - x3
        dy = y1 - y3

        dist = (dx * dx + dy * dy) ** .5
        return dist, (x1, y1)

    u = ((x3 - x1) * px + (y3 - y1) * py) / float(norm)

    if not extend_line:
        if u > 1:
            u = 1
        elif u < 0:
            u = 0

    x = x1 + u * px
    y = y1 + u * py

    dx = x - x3
    dy = y - y3

    dist = (dx * dx + dy * dy) ** .5

    return dist, (x, y)