我有N个矩形,所有相同的尺寸 rectWidth * rectHeight 。 我有一个尺寸 areaWidth * areaHeight 的区域。 我想在区域内放置N个矩形,保持矩形的纵横比,调整矩形的大小以使它们合适。 在矩形之间,我想要一个空格的间距。
矩形的尺寸应该是什么,以使它们都适合矩形并保持纵横比?
答案 0 :(得分:2)
让N个矩形 设矩形是大小(cw,ch),其中0 <0。 c≤1 让你想要的区域大小(W,H) 设s≥0是矩形之间的间距。
a的水平尺寸&gt;水平堆叠的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&lt; c≤1
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)成立,我们假设不失一般性。
因为必须采用{1,2,...,N}中的一个值,
c必须取{W / w,(W - s)/ 2w,(W - 2s)/ 3w,......,(W - (N - 1)s)/ Nw}中的一个值。
类似的推理给出了在第二个不等式(对于b)很紧的情况下必须从中得出的值列表。
如果合并这两个值列表,则最多可以有2N个可能的值c可以采用最优解。对这些值进行排序,然后二元搜索此列表中有可行a和b的最大c。
检查c值是否可行的方法是设置
a = floor((W + s)/(cw + s))
b = floor((H + s)/(ch + s))
然后检查ab≥N。
答案 1 :(得分:1)
这个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大小并确定画布宽度是否大于容器宽度。如果canvas更大,我们会行++并再次调用该函数。
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];
如果您还关心找到MAX rect size并且不仅适合它,那么也应该对列进行迭代,并且应该选择更大的rect大小:
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])]