This code randomly puts shapes on a background, and sees if the added shape brings the new image closer to a target image. If the shape does, it is jittered more until it’s done improving the image for a certain number of iterations. For example, using 40 triangles on the Lena image:
Neat. How about rectangles?
Squares! And Circles!
Eight-sided shapes! They’re not always convex, but whatever. Makes for more interesting shapes.
These aren’t optimal, but they work pretty well.