Thanks, D. I'm glad someone finds it useful!
Yes, you can use the frame node to animate permutations. Just hook it to the Candidates node (instead of Range), render the Candidates node, and hit play.
The Candidates node only returns a pattern if there are no collisions - which varies depending on the seed provided. So you may have to advance through dozens of frames before you find a viable one. By hitting play you do this automatically, but each pattern flashes by pretty quickly.
(You could fix this by generating a bunch of candidates ahead of time and then filter out the nulls so that you could advance one viable pattern per frame.)
Detecting collisions among an arbitrary number of objects is a pain because you have to examine every possible pair. That's what I do here. I generate every possible pairing; with only five shapes there are 10 possible pairs [ n * (n-1) / 2 ].
To detect a collision I use the compound node to do an intersection and measure the resulting area (using the handy area node from my node library). If the objects do not overlap the area will be zero. I then sum these areas for all possible pairs. If that sum is zero there are no collisions.
This works but is not very efficient. Actually generating each intersection is wasteful. Professional collision detectors do things like ending loops on the first collision (hard to do in NodeBox since we have no loops) and reducing the number of pairs to test by doing a pre-analysis of objects based on rough locations (which gets complicated and is hard to generalize).
I agree that some kind of random placement and/or collision node(s) would be useful additions to my library. I hesitate to use the nodes I made for this demo, though, because they are so inefficient. I could make a faster one in Python but then you'd have to add code each time you used it.
It's also awkward that the place node returns null if there is a collision. It would be nice to guarantee a viable placement each time, but to do that you'd have to keep iterating until you found one, and if the bounding is tight this could require an unpredictably large number of iterations (if the bounding is too tight collisions cannot be avoided, but this is hard to predict ahead of time).
An alternative would be to always try 10 (or some other number) of candidates and return the one with the fewest collisions - but that would slow the node by a factor of 10 and not guarantee a collision-free placement.
I'll think about it some more. If you have any use cases or things you would want to see in such a node that would help.
Finally I completely agree that this technique is very useful in generative designs. That's why I thought this was such an interesting use case - and one worth solving.
Thanks again for commenting!
John