call function on all combinations of a list
Posted: Sat Feb 06, 2010 3:09 pm
i'm creating a little physics engine which manages a list a of collidable objects. in order to calculate all occurring collisions i need to combine every item in the list with each other and check for the collision. to avoid NxN checks i want to take the first element and check it against the rest, take the next and check it against the rest and so on. the result should be a "collision list" of collision pairs: ((box1 circle3) (circle7 circle3) (box2 circle7)). is there a existing function or idiom which handles these combinations?
simple sample source
simple sample source

Code: Select all
(defun combine-if (test func list)
; 1. combines every item with the rest
; 2. check if test is true on current item and rest item
; 3. if so, call func and add the result to the result list
...)
(combine-if #'= #'cons '(1 2 3 2 1))
; in my little physics engine i would use collidep and cons
; on a list of collidable objects here!
take 1
check against (2 3 2 1)
(= 1 2)? => NIL
(= 1 3)? => NIL
(= 1 2)? => NIL
(= 1 1)? => T
(cons 1 2) => (1 . 2) added to result list
take 2
check against 3 2 1
(= 2 3)? => NIL
(= 2 2)? => T
(cons 2 2) => (2 . 2) added to result list
(= 2 1)? => NIL
and so on until there is only 1 item left which cannot be checked against another item
result ((1. 1) (2 . 2))