Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++

Rectangle Tiling Algorithm

0.00/5 (No votes)
30 Jan 2011CPOL 9.4K  
This article deserves recognition for its fun potential. After reading it, I decided to try it out by building a simple HTML/JavaScript application to try it out. I used jQuery and a jQuery plugin, SVG. The work is simple and not very elegant, but I had fun putting it together.The HTML...
This article deserves recognition for its fun potential. After reading it, I decided to try it out by building a simple HTML/JavaScript application to try it out. I used jQuery and a jQuery plugin, SVG. The work is simple and not very elegant, but I had fun putting it together.

The HTML Code
Note that the references to the jQuery and SVG libraries have been shortened as if to suggest that they live in the same folder as the app. You will have to download and install these libraries and adjust these references to reflect your installation.

The library paths will have to be adjusted to yours
XML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
    <title>Tiles</title>
    <style type="text/css">
        @import "C:\Users\Rodrigo\Dropbox\Silveira\SilveiraConsulting\Gildhalle\jquery\jquery.svg.package-1.4.3\jquery.svg.css";
        #svgbasics { width: 400px; height: 300px; border: 1px solid #484; }
    </style>
    <script type="text/javascript" src="C:\Users\Rodrigo\Dropbox\Silveira\SilveiraConsulting\Gildhalle\jquery\jquery-ui-1.8.4.custom\js\jquery-1.4.2.min.js"></script>
    <script type="text/javascript" src="C:\Users\Rodrigo\Dropbox\Silveira\SilveiraConsulting\Gildhalle\jquery\jquery.svg.package-1.4.3\jquery.svg.js"></script>
    <script type="text/javascript" src="tiling_1.js"></script>
</head>
<body>
    <h1>Tiling</h1>
    <h2>Collect the information</h2>
    <div>
        <div id="collectTilingInformation" >
            <form id="collectTilingInformationForm" style="width: 99%">
                <input type="hidden" name="Hidden" value="hiddenValue"></input>
                <table>
                    <tbody>
                        <tr>
                            <td>Tiles</td>
                        </tr>
                        <tr>
                            <td><input name="numberOfTiles" type="text" value="6"></input></td>
                        </tr>
                    </tbody>
                </table>
            </form>
        </div>
    </div>
    <h2>Show the Tiles</h2>
    <div id="svgbasics"></div>
    <div id="collectTilingInformationForm" class="im_buttons_right">
        <button type="button" id="tiles">Generate Tiles</button>
    </div>
</html>


JS
C#
/**
 * @param iReactangles The number of tiles to generate
 * @returns oTiles An array of integers, where each integer represents the number
 *          of tiles of the row represented by its index
 */
$(function() {
    $('#svgbasics').svg({onLoad: drawInitial_1});
    $('#tiles').click(drawTiles);
    $('#clear').click(function() {
        $('#svgbasics').svg('get').clear();
    });
    //$('#export').click(function() {
       //var xml = $('#svgbasics').svg('get').toSVG();
       //$('#svgexport').html(xml.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;'));
    //});
});

function drawInitial_1(svg) {
}
var colours = ['purple', 'red', 'orange', 'yellow', 'lime', 'green', 'blue', 'navy', 'black'];
function drawTiles() {
        var i = 0;
        //Get the jQuery SVG drawing area
        var svg = jQuery('#svgbasics').svg('get');

        //Get the number of tiles to draw
    var formValues = {};
    var $inputs = jQuery('#collectTilingInformationForm :input');
    $inputs.each(function() {
        formValues[this.name] = jQuery(this).val();
    });
    iTiles = formValues.numberOfTiles
        console.log("Number of Tiles to draw: " + iTiles);
    //Get an array where each entry represents a row and the entry value the number
    //of tiles to draw for the row
        tiles = tileRectangularArea(iTiles);
        for (i in tiles) {
                console.log("Tiles in row " + (i + 1) + ": " + tiles[i]);
        }
        //Clear the existing tiles
        jQuery('#svgbasics').svg('get').clear();
        //Get the dimensions of the drawing area
        drawingAreaHeight = jQuery('#svgbasics').height();
        drawingAreaWidth = jQuery('#svgbasics').width();
        console.log("Drawing area height: " + drawingAreaHeight);
        console.log("Drawing area width: " + drawingAreaWidth);
        //Draw the tiles
        var iTileX = 0;
        var iTileY = 0;
        for (i in tiles) {
                //Get the number of tiles for this row
                iTilesInRow = tiles[i];
                //Calculate the dimensions of the tiles for this row
                tilesHeight = Math.floor(drawingAreaHeight/iTilesInRow);
                tilesWidth = Math.floor(drawingAreaWidth/iTilesInRow);
                console.log("Tiles height for row " + i + ": " + tilesHeight);
                console.log("Tiles width for row " + i + ": " + tilesWidth);
                //Draw the tiles for this row
                for (j = 0; j < iTilesInRow; j++) {
                        //Draw a tile
                svg.rect(iTileX, iTileY,tilesWidth, tilesHeight,
                        {fill: colours[random(9)], stroke: colours[random(9)],
                        'stroke-width': random(5) + 1});
                        //Compute drawing coordinate x of the next tile to the right of the
                // one just drawn
                        iTileX += tilesWidth;
                }
                //Set the tiles' drawing coordinates for the next row to be drawn
                iTileX = 0;
                iTileY += tilesHeight;
        }
}
function random(range) {
    return Math.floor(Math.random() * range);
}
/**
 * A function to compute the number of tiles to be drawn into a rectangle
 * Posted to the Code Project by Ataul Mukit
 * See: http://www.codeproject.com/Tips/149445/Rectangle-Tiling-Algorithm.aspx
 * @param iRectangles
 * @returns
 */
function tileRectangularArea(iRectangles) {
        var i = 0,
            iSections = 0,
            aColumnsPerRow = null,
                fRoot = 0.0,
                fSquareRoot = 0.0,
                iRoundedRoot = 0,
                iRowCount = 0,
                iColCount = 0,
                iLeftOver = 0,
                iLeft = 0,
                oTiles = null;
        if (iRectangles == 0) {
                //do nothing
        }
        else {
                aColumnsPerRow = [];
                if (iRectangles <= 4) {
                        aColumnsPerRow[0] = iRectangles
                }
                else {
                        fRoot = iRectangles * 1.0;
                        fSquareRoot = Math.sqrt(fRoot)
                        iRoundedRoot = Math.floor(fSquareRoot);
                        iRowCount = iRoundedRoot;
                        iColCount = iRoundedRoot;
                        iLeftOver = iRectangles - iRowCount*iColCount;
                        iDistribution = Math.floor(iLeftOver/iRowCount);
                        iColCount += iDistribution;
                        iLeft = iRectangles - iRowCount*iColCount;
                        iStartAddingIndex = iRowCount - iLeft;
                        for (i = 0; i < iRowCount; i++) {
                                if (i == iStartAddingIndex) {
                                        iColCount++;
                                        iStartAddingIndex = -1;
                                }
                                aColumnsPerRow[i] = iColCount;
                        }
                }
        }
        return aColumnsPerRow;
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)