Dividing a Rectangular Area

2006-08-21

This is code I came up with to split a rectangular area into N number of (almost) equally-sized rectangles. It comes with a function that favors rectangles of greater height where possible, and another that favors width. Both use the same core logic.

The code is used by calling either divideRectangle_favorWidth() or divideRectangle_favorHeight(). The number parameter refers to the number of rectangles to be tiled, and gutter specifies the amount of space to put between the rectangles. Both functions return an array that is 4 times as long as the number of rectangles to be tiled. So it should be iterated over in steps of four. Element 0 is the X position of the first rectangle. Element 1 is the Y position. Element 2 is the width. Element 3 is the height. Element 4 is the X position of the second rectangle and so on.

This was an essential piece to my alpha version of Knox (screenshot here), where it's used to tile virtual terminals. The code presented here is a form of pseudocode, but you can get a zip of the C code here.

int[] divideRectangle_favorWidth(areaWidth, areaHeight, number, gutter) {
    columns = round( sqrt( number) );
    rows = ceil( number / columns );
    return divideRectangle(areaWidth, areaHeight, columns, rows, number, gutter);
}

int[] divideRectangle_favorHeight(areaWidth, areaHeight, number, gutter) {
    rows = round( sqrt( number) );
    columns = ceil( number / rows );
    return divideRectangle(areaWidth, areaHeight, columns, rows, number, gutter);
}

int[] divideRectangle(areaWidth, areaHeight, rectangleColumns, rectangleRows, number, gutter) {
    startCoordinates = int[];
    rectangleWidth = areaWidth / rectangleColumns;
    rectangleHeight = areaHeight / rectangleRows;
    x = y = 0;
    row = -1;
    for(i = 0, j = 0; i < number; i++) {
        if(i % rectangleColumns == 0) {
            row++;
            y = row * rectangleHeight;
            if(row == rectangleRows - 1 && number % rectangleColumns != 0) {
                rectangleColumns = number % rectangleColumns;
                rectangleWidth = areaWidth / rectangleColumns;
                i = 0;
                number = rectangleColumns;
            }
        }
        x = (i % rectangleColumns) * rectangleWidth;
        startCoordinates[j] = x;
        startCoordinates[j + 1] = y;
        startCoordinates[j + 2] = rectangleWidth - gutter;
        startCoordinates[j + 3] = rectangleHeight - gutter;
        j += 4;
    }
    return startCoordinates;
}

 


 

Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.