view skaapsteker/utils.py @ 627:35919d12b792

Path-based collision minimisation and axis-projection backout.
author Jeremy Thurgood <firxen@gmail.com>
date Sat, 07 May 2011 20:28:06 +0200
parents 4ffa9d159588
children 0675f390653c
line wrap: on
line source

import operator
import functools


def mktuple(thing):
    if isinstance(thing, (list, tuple)):
        return tuple(thing)
    return (thing, thing)


def coord_op(fun, coord, operand):
    operand = mktuple(operand)
    return (fun(coord[0], operand[0]),
            fun(coord[1], operand[1]))


def mk_cop(op):
    return functools.partial(coord_op, op)


def mk_cuop(op):
    return lambda coord: (op(coord[0]), op(coord[1]))


cadd = mk_cop(operator.add)
csub = mk_cop(operator.sub)
cmul = mk_cop(operator.mul)
cdiv = mk_cop(operator.div)
cclamp = mk_cop(lambda a, b: max(min(a, b), -b))
cabsmax = mk_cop(lambda a, b: a if abs(a) > abs(b) else b)

cint = mk_cuop(int)
cneg = mk_cuop(lambda a: -a)
cabs = mk_cuop(abs)


def rect_projection(rect1, rect2):
    if not rect1.colliderect(rect2):
        # No collision?
        return (0, 0)

    if rect1.center[0] < rect2.center[0]:
        x_projection = rect2.left - rect1.right
    else:
        x_projection = rect2.right - rect1.left

    if rect1.center[1] < rect2.center[1]:
        y_projection = rect2.top - rect1.bottom
    else:
        y_projection = rect2.bottom - rect1.top

    if abs(x_projection) < abs(y_projection):
        return (x_projection, 0)
    return (0, y_projection)