将区域划分为给定数量的正方形

时间:2013-12-03 12:56:43

标签: javascript algorithm geometry packing

我有一个可以由用户调整大小的DIV元素。进入这个DIV我想绘制一定数量的正方形。现在我需要找出,正方形的完美边长是多少,以便所有都适合DIV而不会溢出。

这是我到目前为止所得到的:

function CalcSize (){
    var number = 23; // Example-Number
    var area = jQuery('#container').height() * jQuery('#container').width();
    var elementArea = parseInt(area / number);
    var sideLength = parseInt(Math.sqrt(elementArea));
    return sideLength;
}

这使得正方形太大,因为它不会“扔掉”无法用正方形填充的空间。通过搜索这个问题,我找到了Packing Problem和Treemapping,但两者都没有帮助我解决我的问题,因为说实话,我缺乏数学技能,据我所知,解决方案允许非正方形和旋转等。

谢谢!

更新

我目前使用一种非常粗略的方法来调整方块的大小,不断调整它们的大小并查看它们是否溢出。这种方法给了我正确的结果,但在性能上非常糟糕。我相信这可以通过计算来实现。

Link to a screenshot

2 个答案:

答案 0 :(得分:3)

这是一个使用整个宽度的算法,所有未使用的空间都在底部。这并不总是给出最大可能的正方形,但它会以一致的方式运行,看起来应该很好。

请注意,while循环通常不应超过一次或两次迭代。

function CalcSize (){
    var number = 23; // Example-Number
    var width = jQuery('#container').width();
    var height = jQuery('#container').height();
    var area = height * width;
    var elementArea = parseInt(area / number);

    // Calculate side length if there is no "spill":
    var sideLength = parseInt(Math.sqrt(elementArea));

    // We now need to fit the squares. Let's reduce the square size 
    // so an integer number fits the width.
    var numX = ceil(width/sideLength);
    sideLength = width/numX;
    while (numX <= number) {
        // With a bit of luck, we are done.
        if (floor(height/sideLength) * numX >= number) {
            // They all fit! We are done!
            return sideLength;
        }
        // They don't fit. Make room for one more square i each row.
        numX++;
        sideLength = width/numX;
    }
    // Still doesn't fit? The window must be very wide
    // and low.
    sideLength = height;
    return sideLength;
}

答案 1 :(得分:0)

根据图像,我假设您可以使用垂直和水平未使用的空格,只要长度最大化。

基本上这是一个线性规划问题(实际上它是整数编程问题)。我们有以下不等式,我们希望最大化长度。

行,列和长度是未知数;和n,宽度和高度给出:

rows >= 1
cols >= 1
rows*cols >= n
rows*length <= height
cols*length <= width
maximize length

从最后3个方程中得到的估计是正确的:长度&lt; = sqrt(高度*宽度/ n)。 您仍然需要循环遍历可能的范围以获取整数值。使用Binary Search可以更快地完成这项工作。