Algorithm 在保持纵横比的区域内拟合N个矩形

Algorithm 在保持纵横比的区域内拟合N个矩形,algorithm,math,rectangles,Algorithm,Math,Rectangles,我有N个矩形,所有尺寸都相同矩形宽度*矩形高度。 我有一个尺寸为区域宽度的区域*区域高度。 我想在区域内拟合N个矩形,保持矩形的纵横比,调整矩形的大小使其适合。 在矩形之间,我希望间隔为空格 矩形的尺寸应该是多少才能使它们都适合矩形并保持纵横比?这个javaScript解决方案怎么样 var areaHeight = window.innerHeight; //set here your area height var areaWidth = window.innerWidth; /

我有N个矩形,所有尺寸都相同矩形宽度*矩形高度。 我有一个尺寸为区域宽度的区域*区域高度。 我想在区域内拟合N个矩形,保持矩形的纵横比,调整矩形的大小使其适合。 在矩形之间,我希望间隔为空格


矩形的尺寸应该是多少才能使它们都适合矩形并保持纵横比?

这个javaScript解决方案怎么样

var areaHeight = window.innerHeight;   //set here your area height
var areaWidth = window.innerWidth;     //set here your area width
var N = 216;                           //set amount of rectangles you want to fit
var rectRatio = 9/4;                   //set rectangle ratio
var gutter = [5, 10];                  //set x and y spacing between rectangles
var cols, rows, rectHeight, rectWidth; //variables that we need to calculate
该函数假定矩形网格(画布)始终适合容器区域的高度。将行数馈送给函数,它计算rect大小并确定画布宽度是否大于容器宽度。如果画布更大,则执行rows++并再次调用该函数

function rowIterator(iterator) {
   rows = iterator;
   cols = Math.ceil(N/rows);  

   rectHeight = (areaHeight - (rows-1)*gutter[1])/rows;          
   rectWidth = rectHeight*rectRatio;

   if (cols * rectWidth + (cols - 1)*gutter[0] > areaWidth) {
       rowIterator(rows + 1);
   }
}

rowIterator(1);                       //feed initial value
var size1 = [rectWidth, rectHeight];
如果您还关心查找最大rect size,并且不仅适合它,那么还应该对列进行迭代,并选择更大的rect size:

function colIterator(iterator) {
   cols = iterator;
   rows = Math.ceil(N/cols);

   rectWidth = (areaWidth - (cols - 1)*gutter[0])/cols;
   rectHeight = rectWidth/rectRatio;

   if (rows * rectHeight + (rows - 1)*gutter[1] > areaHeight) {
       colIterator(cols + 1);
   }
}
colIterator(1);
var size2 = [rectWidth, rectHeight];
两个迭代器的总迭代次数约为N,最大矩形大小为:

optimalRectSize = [Math.max(size1[0], size2[0]), Math.max(size1[1], size2[1])]

设N个矩形。
设矩形的大小为(cw,ch),其中0 让您想要适合的区域大小为(W,H)。
让我们≥ 0是矩形之间的间距

水平堆叠的>0个矩形的水平尺寸为acw+(a-1)s.
我们知道acw+(a-1)s≤ W

垂直堆叠的b>0矩形的垂直尺寸为bch+(b-1)s.
我们知道bch+(b-1)s≤ H

然后我们有下面的优化问题

最大c
受制于
A.≤ (W+s)/(cw+s)
B≤ (H+s)/(ch+s)
ab≥ N
0 a、 b>0和整数

现在考虑以下不等式:

a≤ (W+s)/(cw+s)
B≤ (H+s)/(ch+s)

任何最优解都必须至少使其中一个成为紧不等式。
也就是说,对于最优解(a,b,c),至少以下一项成立

a=(W+s)/(cw+s)&左右箭头;c=(W-s(a-1))/wa
b=(H+s)/(ch+s)&左右箭头;c=(H-s(b-1))/wb

假设a=(W+s)/(cw+s)成立,但不失一般性。
由于a必须取{1,2,…,N}中的一个值,
c必须取{W/W,(W-s)/2w,(W-2s)/3w,…(W-(N-1)s)/Nw}中的一个值

类似的推理给出了在第二个不等式(对于b)很紧的情况下,c必须从中提取的值列表

如果将这两个值列表合并,则c在最佳解决方案中最多可以获得2N个可能值。对这些值进行排序,然后二进制搜索此列表中存在可行a和b的最大值c

检查c值是否可行的方法是设置

a=地板((W+s)/(cw+s))
b=地板((H+s)/(ch+s))


然后检查ab≥ N.

您需要更好地指定这一点。现在的问题是非常欠约束的:我可以将所有矩形的大小调整为0x0。你想要一个特殊的位置吗?它们是否应该按相同的因素调整大小?嗨,托马斯,谢谢你的回复。放置不是问题,我将矩形馈送给放置它们的控件。所有N个矩形都具有相同的尺寸,并且在新的情况下必须保持相同的尺寸。我希望它们是它们原来的尺寸(rectWidth*rectHeight),或者如果它们不都适合的话,则更小。算法的结果应该是调整它们大小的因素,以便它们适合。如果这个因子>1,我保持原样,如果因子<1,我用这个因子调整所有矩形的大小。我希望这能很好地解释要求和约束条件。我认为问题应该重新表述为:矩形的最大尺寸应该是多少,以使它们都适合矩形并保持纵横比?我尝试了一种直接公式方法,它告诉我a应该接近NR/r或b应该接近NR/r,R表示面积的纵横比,R和N分别表示面积的纵横比和矩形数,a和b分别表示面积宽度和高度中的矩形数。在我考虑间距之前,有人能找到给出错误结果的配置吗?这看起来很棒。。。但需要对此进行研究:-)我们(Pi=31415926&I)将尝试将其转换为JavaScript函数:-)嗯。。。所以我需要在N个元素上做2个循环来收集c的所有可能值。这比迭代次数少于N次的解决方案快多少?我要对我的答案做一些解释…@31415926你发布的方法的问题是它不总是有效的。@31415926来自对问题的评论:“我希望它们是原始尺寸(rectWidth*rectHeight),或者如果它们不都合适的话更小。”你对这些批评有点傻了,所以我不再讨论了。@31415926如果不是因为假设
c,你的算法和这个算法是完全相同的