def intersect_line_line(line1_start, line1_end, line2_start, line2_end):
    """
    Find the point where the lines (segments) defined by
    ``(line1_start, line1_end)`` and ``(line2_start, line2_end)``
    intersect.  If no intersection occurs, ``None`` is returned.

    >>> intersect_line_line((3, 0), (8, 10), (0, 0), (10, 10))
    (6, 6)
    >>> intersect_line_line((0, 0), (10, 10), (3, 0), (8, 10))
    (6, 6)
    >>> intersect_line_line((0, 0), (10, 10), (8, 10), (3, 0))
    (6, 6)
    >>> intersect_line_line((8, 10), (3, 0), (0, 0), (10, 10))
    (6, 6)
    >>> intersect_line_line((0, 0), (0, 10), (3, 0), (8, 10))
    >>> intersect_line_line((0, 0), (0, 10), (3, 0), (3, 10))

    Ticket #168:
    >>> intersect_line_line((478.0, 117.0), (478.0, 166.0), (527.5, 141.5), (336.5, 139.5))
    (478.5, 141.48167539267016)
    >>> intersect_line_line((527.5, 141.5), (336.5, 139.5), (478.0, 117.0), (478.0, 166.0))
    (478.5, 141.48167539267016)

    This is a Python translation of the ``lines_intersect``, C Code from
    Graphics Gems II, Academic Press, Inc. The original routine was written
    by Mukesh Prasad.

    EULA: The Graphics Gems code is copyright-protected. In other words, you
    cannot claim the text of the code as your own and resell it. Using the code
    is permitted in any program, product, or library, non-commercial or
    commercial. Giving credit is not required, though is a nice gesture. The
    code comes as-is, and if there are any flaws or problems with any Gems
    code, nobody involved with Gems - authors, editors, publishers, or
    webmasters - are to be held responsible. Basically, don't be a jerk, and
    remember that anything free comes with no guarantee.
    """
    x1, y1 = line1_start
    x2, y2 = line1_end
    x3, y3 = line2_start
    x4, y4 = line2_end
    a1 = y2 - y1
    b1 = x1 - x2
    c1 = x2 * y1 - x1 * y2
    r3 = a1 * x3 + b1 * y3 + c1
    r4 = a1 * x4 + b1 * y4 + c1
    if r3 and r4 and r3 * r4 >= 0:
        return None
    a2 = y4 - y3
    b2 = x3 - x4
    c2 = x4 * y3 - x3 * y4
    r1 = a2 * x1 + b2 * y1 + c2
    r2 = a2 * x2 + b2 * y2 + c2
    if r1 and r2 and r1 * r2 >= 0:
        return None
    denom = a1 * b2 - a2 * b1
    x_num = b1 * c2 - b2 * c1
    y_num = a2 * c1 - a1 * c2
    if not denom:
        return None
    elif isinstance(denom, float):
        offset = abs(denom) / 2
        x = (x_num < 0 and x_num - offset or x_num + offset) / denom
        y = (y_num < 0 and y_num - offset or y_num + offset) / denom
    else:
        offset = abs(denom) // 2
        x = (x_num < 0 and x_num - offset or x_num + offset) // denom
        y = (y_num < 0 and y_num - offset or y_num + offset) // denom
    return x, y
