In my office at work, we are not allowed to paint the walls, so I have decided to frame out squares and rectangles, attach some nice fabric to them, and arrange them on the wall.
I am trying to write a method which will take my input dimensions (9' x 8' 8") and min/max size (1' x 3', 2', 4', etc..) and generate a random pattern of squares and rectangles to fill the wall. I tried doing this by hand, but I'm just not happy with the layout that I got, and it takes about 35 minutes each time I want to 'randomize' the layout.
Another idea:
The kd-tree will split the space in a number of rectangles. There might be too much structure for what you want, but its still a neat geeky algorithm.
(see: http://en.wikipedia.org/wiki/Kd-tree)
Edit: Just looked at JTreeMap, looks a bit like this is what its doing.
Since you can pick the size of the rectangles, this is not a hard problem.
I'd say you can do something as simple as:
It might be interesting to parametrize the generation of points, and then make a genetic algorithm. The fitness function will be how much you like the arrangement - it would draw hundreds of arrangements for you, and you would rate them on a scale of 1-10. It would then take the best ones and tweak those, and repeat until you get an arrangement you really like.
I would generate everything in a spiral slowly going in. If at any point you reach a point where your solution is proven to be 'unsolvable' (IE, can't put any squares in the remaining middle to satisfy the constraints), go to an earlier draft and change some square until you find a happy solution.
Pseudocode would look something like:
}
Building off Philippe Beaudoin answer.
There are treemap implementations in other languages that you can also use. In Ruby with RubyTreeMap you could do
However it sorts the rectangles, so it doesn't look very random, but it could be a start. See rubytreemap.rubyforge.org/docs/index.html for more info
I suggest:
Start by setting up a polygon with four vertices to be eaten in varying size (up to maxside) rectangle lumps:
Then choose a random vertex, find polygon lines within (inclusive) 2 X maxside of the line. Find x values of all vertical lines and y values of all horizontal lines. Create ratings for the "goodness" of choosing each x and y value, and equations to generate ratings for values in between the values. Goodness is measured as reducing number of lines in remaining polygon. Generate three options for each range of values between two x coordinates or two y coordinates, using pseudo-random generator. Rate and choose pairs of x and pair of y values on weighted average basis leaning towards good options. Apply new rectangle to list by cutting its shape from the poly array and adding rectangle coordinates to the dest array.
Question does not state a minimum side parameter. But if one is needed, algorithm should (upon hitting a hitch with a gap being too small) not include too small candidates in selection lists (whic will occasionally make them empty) and deselect a number of the surrounding rectangles in a certain radius of the problem with size and perform new regeneration attempts of that area, and hopefully the problem area, until the criteria are met. Recursion can remove progressively larger areas if a smaller relaying of tiles fails.
EDIT
Do some hit testing to eliminate potential overlaps. And eat some spinach before starting the typing. ;)
One solution is to start with x*y squares and randomly merge squares together to form rectangles. You'll want to give differing weights to different size squares to keep the algorithm from just ending up with loads of tiny rectangles (i.e. large rectangles should probably have a higher chance of being picked for merging until they get too big).