from typing import Tuple


def intersects(p1: Tuple[float, float], p2: Tuple[float, float],
               p3: Tuple[float, float], p4: Tuple[float, float]) -> bool:
    """Checks if line segment p1p2 and p3p4 intersect.

    This method, which works by checking relative orientation, allows
    for collinearity, and only checks if each segment straddles the line
    containing the other.
    """
    def subtract(a: Tuple[float, float], b: Tuple[float, float]) \
        -> Tuple[float, float]:
        x1, y1 = a
        x2, y2 = b
        return (x1 - x2), (y1 - y2)
    def cross_product(a: Tuple[float, float], b: Tuple[float, float]) \
        -> float:
        x1, y1 = b
        x2, y2 = a
        return x1 * y2 - x2 * y1

    def direction(a: Tuple[float, float], b: Tuple[float, float],
                  c: Tuple[float, float]) -> float:
        return cross_product(subtract(a, c), subtract(a, b))

    d1 = direction(p3, p4, p1)
    d2 = direction(p3, p4, p2)
    d3 = direction(p1, p2, p3)
    d4 = direction(p1, p2, p4)
    if ((d2 < 0 < d1) or (d1 < 0 < d2)) and \
    ((d4 < 0 < d3) or (d3 < 0 < d4)):
        return True
    return False