def collides(a, b):
    """Return true if the two moving circles collide.

    a and b should have the following attributes:

    x, y - required, current position
    px, py - not required, defaults to x, y, previous frame position
    radius - not required, defaults to 0.5

    (This function is unoptimized.)

    """
    # Current locations.
    xa = a.x
    xb = b.x
    ya = a.y
    yb = b.y

    # Treat b as a point, we only need one radius.
    try:
        radius = a.radius + b.radius
    except AttributeError:
        radius = getattr(a, 'radius', 0.5) + getattr(b, 'radius', 0.5)

    # Previous frame locations.
    try: pxa = a.px
    except KeyError: pxa = xa
    try: pya = a.py
    except KeyError: pya = ya
    try: pxb = b.px
    except KeyError: pxb = xb
    try: pyb = b.py
    except KeyError: pyb = yb

    # Translate b's final position to be relative to a's start.
    # And now, circle/line collision.
    dir_x = pxa + (xb - xa) - pxb
    dir_y = pya + (yb - ya) - pyb

    diff_x = pxa - pxb
    diff_y = pya - pyb
    if (dir_x < 0.0001 and dir_x > -0.0001
        and dir_y < 0.0001 and dir_y > -0.0001):
        # b did not move relative to a, so do point/circle.
        return diff_x * diff_x + diff_y * diff_y < radius * radius

    # dot(diff, dir) / dot(dir, dir)
    t = (diff_x * dir_x + diff_y * dir_y) / (dir_x * dir_x + dir_y * dir_y)
    if t < 0:
        t = 0
    elif t > 1:
        t = 1

    dist_x = pxa - (pxb + dir_x * t)
    dist_y = pya - (pyb + dir_y * t)

    # dist_sq < radius_sq
    return dist_x * dist_x + dist_y * dist_y <= radius * radius