Search code examples
javaactionscript-3algorithmbin

Break up a square or rectangle into a large number of randomly sized squares or rectangles


I'm trying to break up a square or rectangle into a large number of randomly sized squares or rectangles so that none are overlapping.

Ok of course others have asked this the best thread I found is How to fill a square with smaller squares/rectangles?

The solution seems to be either through bin packing or some sort of tree map.

But what I'm looking for is the actual algorithm in Java, Javacript , actionscript or even C.


Solution

  • The provided code creates a k-d tree. You can use this to draw lines on your rectangle that will divide it into smaller rectangles. After you've got your tree you can use it as follows to divide your region up into these rectangles:

    1. Pick the node at the root of the tree.
    2. Draw a vertical line through this point.
    3. Choose it's left child, draw a horizontal line through this point on the left side of the line you just drew through it's parent (this line stops at the line you just drew).
    4. Choose it's right child, draw a horizontal line through this point on the right side of the line you just drew through it's parent (this line also stops at the line you drew through the parent).
    5. Do this recursively, switching between vertical and horizontal lines at each level of the tree.

    Code:

    int MAX_HEIGHT = 100;
    int MAX_WIDTH = 100;
    int NUM_POINTS = 6;
    
    
    // Generate random list of points
    List<Point> pointList = new List<Point>();
    
    Random rand = new Random();
    
    for(int i = 0; i < NUM_POINTS ; i++)
    {
        pointList.add(new Point(rand.nextInt(MAX_HEIGHT), rand.nextInt(MAX_WIDTH));
    }
    
    BinaryTree tree = CreateKDTree(pointList, 0);
    
    
    // Recursive function for creating a K-D Tree from a list of points
    // This tree can be used to draw lines that divide the space up
    // into rectangles.
    public BinaryTree CreateKDTree(List<Point> pointList, int depth)
    {
        // Have to create the PointComparator class that just selects the
        // specified coordinate and sorts based on that
        Coordinate coord= depth % 2 == 0 ? X_COORDINATE : Y_COORDINATE
        Collections.sort(pointList, new PointComparator(coord));
    
        int median = pointList.size() / 2;
    
         // unfortunately Java doesn't have a BinaryTree structure so
         // you have to create this too
        BinaryTree node = new BinaryTree(pointList[median]);
    
        if(pointList.size() == 1) return node;
    
        if(median > 0)
            node.left(CreateKDTree(pointList.subList(0, median), depth + 1);
    
        if(median + 1 < subList.size())
            node.right(CreateKDTree(pointList.subList(median + 1, subList.size()), depth + 1);
    
        return node; 
    }