def get_points(orig, dest, taillen):
    """Return a pair of lists of points for use making an arrow.

    The first list is the beginning and end point of the trunk of the arrow.

    The second list is the arrowhead.

    """
    # Adjust the start and end points so they're on the first non-transparent pixel.
    # y = slope(x-ox) + oy
    # x = (y - oy) / slope + ox
    ox, oy = orig.center
    ow, oh = orig.size
    dx, dy = dest.center
    dw, dh = dest.size
    if ox < dx:
        leftx = ox
        rightx = dx
        xco = 1
    elif ox > dx:
        leftx = ox * -1
        rightx = dx * -1
        xco = -1
    else:
        # straight up and down arrow
        return up_and_down(orig, dest, taillen)
    if oy < dy:
        boty = oy
        topy = dy
        yco = 1
    elif oy > dy:
        boty = oy * -1
        topy = dy * -1
        yco = -1
    else:
        # straight left and right arrow
        return left_and_right(orig, dest, taillen)
    slope = (topy - boty) / (rightx - leftx)
    # start from the earliest point that intersects the bounding box.
    # work toward the center to find a non-transparent pixel
    # y - boty = ((topy-boty)/(rightx-leftx))*(x - leftx)
    if slope <= 1:
        for rightx in range(
                int(rightx - dw / 2),
                int(rightx)+1
        ):
            topy = slope * (rightx - leftx) + boty
            if dest.collide_point(rightx * xco, topy * yco):
                rightx = float(rightx - 1)
                for pip in range(10):
                    rightx += 0.1 * pip
                    topy = slope * (rightx - leftx) + boty
                    if dest.collide_point(rightx * xco, topy * yco):
                        break
                break
        for leftx in range(
                int(leftx + ow / 2),
                int(leftx)-1,
                -1
        ):
            boty = slope * (leftx - rightx) + topy
            if orig.collide_point(leftx * xco, boty * yco):
                leftx = float(leftx + 1)
                for pip in range(10):
                    leftx -= 0.1 * pip
                    boty = slope * (leftx - rightx) + topy
                    if orig.collide_point(leftx * xco, boty * yco):
                        break
                break
    else:
        # x = leftx + ((rightx-leftx)(y - boty))/(topy-boty)
        for topy in range(
            int(topy - dh / 2),
            int(topy) + 1
        ):
            rightx = leftx + (topy - boty) / slope
            if dest.collide_point(rightx * xco, topy * yco):
                topy = float(topy - 1)
                for pip in range(10):
                    topy += 0.1 * pip
                    rightx = leftx + (topy - boty) / slope
                    if dest.collide_point(rightx * xco, topy * yco):
                        break
                break
        for boty in range(
            int(boty + oh / 2),
            int(boty) - 1,
            -1
        ):
            leftx = (boty - topy) / slope + rightx
            if orig.collide_point(leftx * xco, boty * yco):
                boty = float(boty + 1)
                for pip in range(10):
                    boty -= 0.1 * pip
                    leftx = (boty - topy) / slope + rightx
                    if orig.collide_point(leftx * xco, boty * yco):
                        break
                break

    rise = topy - boty
    run = rightx - leftx

    try:
        start_theta = atan(rise/run)
    except ZeroDivisionError:
        return up_and_down(orig, dest, taillen)
    try:
        end_theta = atan(run/rise)
    except ZeroDivisionError:
        return left_and_right(orig, dest, taillen)

    # make the little wedge at the end so you can tell which way the
    # arrow's pointing, and flip it all back around to the way it was
    top_theta = start_theta - fortyfive
    bot_theta = pi - fortyfive - end_theta
    xoff1 = cos(top_theta) * taillen
    yoff1 = sin(top_theta) * taillen
    xoff2 = cos(bot_theta) * taillen
    yoff2 = sin(bot_theta) * taillen
    x1 = (rightx - xoff1) * xco
    x2 = (rightx - xoff2) * xco
    y1 = (topy - yoff1) * yco
    y2 = (topy - yoff2) * yco
    startx = leftx * xco
    starty = boty * yco
    endx = rightx * xco
    endy = topy * yco
    return (
        [startx, starty, endx, endy],
        [x1, y1, endx, endy, x2, y2]
    )
def get_points ( orig , dest , taillen ) : ox , oy = orig . center ow , oh = orig . size dx , dy = dest . center dw , dh = dest . size if ox < dx : leftx = ox rightx = dx xco = 1 elif ox > dx : leftx = ox * - 1 rightx = dx * - 1 xco = - 1 else : return up_and_down ( orig , dest , taillen ) if oy < dy : boty = oy topy = dy yco = 1 elif oy > dy : boty = oy * - 1 topy = dy * - 1 yco = - 1 else : return left_and_right ( orig , dest , taillen ) slope = ( topy - boty ) / ( rightx - leftx ) if slope <= 1 : for rightx in range ( int ( rightx - dw / 2 ) , int ( rightx ) + 1 ) : topy = slope * ( rightx - leftx ) + boty if dest . collide_point ( rightx * xco , topy * yco ) : rightx = float ( rightx - 1 ) for pip in range ( 10 ) : rightx += 0.1 * pip topy = slope * ( rightx - leftx ) + boty if dest . collide_point ( rightx * xco , topy * yco ) : break break for leftx in range ( int ( leftx + ow / 2 ) , int ( leftx ) - 1 , - 1 ) : boty = slope * ( leftx - rightx ) + topy if orig . collide_point ( leftx * xco , boty * yco ) : leftx = float ( leftx + 1 ) for pip in range ( 10 ) : leftx -= 0.1 * pip boty = slope * ( leftx - rightx ) + topy if orig . collide_point ( leftx * xco , boty * yco ) : break break else : for topy in range ( int ( topy - dh / 2 ) , int ( topy ) + 1 ) : rightx = leftx + ( topy - boty ) / slope if dest . collide_point ( rightx * xco , topy * yco ) : topy = float ( topy - 1 ) for pip in range ( 10 ) : topy += 0.1 * pip rightx = leftx + ( topy - boty ) / slope if dest . collide_point ( rightx * xco , topy * yco ) : break break for boty in range ( int ( boty + oh / 2 ) , int ( boty ) - 1 , - 1 ) : leftx = ( boty - topy ) / slope + rightx if orig . collide_point ( leftx * xco , boty * yco ) : boty = float ( boty + 1 ) for pip in range ( 10 ) : boty -= 0.1 * pip leftx = ( boty - topy ) / slope + rightx if orig . collide_point ( leftx * xco , boty * yco ) : break break rise = topy - boty run = rightx - leftx try : start_theta = atan ( rise / run ) except ZeroDivisionError : return up_and_down ( orig , dest , taillen ) try : end_theta = atan ( run / rise ) except ZeroDivisionError : return left_and_right ( orig , dest , taillen ) top_theta = start_theta - fortyfive bot_theta = pi - fortyfive - end_theta xoff1 = cos ( top_theta ) * taillen yoff1 = sin ( top_theta ) * taillen xoff2 = cos ( bot_theta ) * taillen yoff2 = sin ( bot_theta ) * taillen x1 = ( rightx - xoff1 ) * xco x2 = ( rightx - xoff2 ) * xco y1 = ( topy - yoff1 ) * yco y2 = ( topy - yoff2 ) * yco startx = leftx * xco starty = boty * yco endx = rightx * xco endy = topy * yco return ( [ startx , starty , endx , endy ] , [ x1 , y1 , endx , endy , x2 , y2 ] )
Return a pair of lists of points for use making an arrow.

    The first list is the beginning and end point of the trunk of the arrow.

    The second list is the arrowhead.