一尘不染

根据n个项目,总面积和H:W比率创建最佳网格

algorithm

我正在创建一个应用程序,该应用程序使用多个相等大小的矩形并将它们放置在屏幕上的网格中。我已经完成了用于调整单元格中矩形的大小和居中的大多数逻辑,但是对于定义矩形必须符合的网格的实际部分却遇到了麻烦。

理想情况下,最后我将拥有一个类似以下的函数(伪代码):

function getGridDimensions (rect surface, int numItems, float hwRatio) {
    // do something to determine grid-height and grid-width
    return gridDimensions;
}

我最初的尝试涉及到以下内容:

gridHeight = surface.width / sqrt(numItems);
gridWidth = surface.height / sqrt(numItems);

如果我的项目都是完美的正方形,这将很好地工作,但是由于它们是矩形,因此每个单元格中都有许多未使用的空白。

对Google的任何想法或条款可以为我指明正确的方向吗?


阅读 192

收藏
2020-07-28

共1个答案

一尘不染

我不清楚您的某些输入参数,但我假设您具有Rectangle的高度和宽度,矩形的数量以及理想的高宽比(即,首选gridheight / gridwidth)。

如果是这种情况,那么我可能会从“规格化”您的尺寸开始,因此出于以下计算的目的,我们说宽度单位与矩形的宽度相同,同样对于高度单位也是如此。如果实际单位的高度/宽度比率为k,则矩形单位的高度/宽度比率将为k * RectWidth / RectHeight。我称它为K。

因此,根据定义,现在每个矩形的面积为1,因此我们的总面积为N,其中N是项数。然后,我们可以通过说gridHeight * gridWidth =
N和gridHeight / gridWidth = K来近似我们的高度添加宽度,以给出自己喜欢的网格长宽比

有了这些,我们得到gridHeight = sqrt(KN)和gridWidth = sqrt(N / K)。

如果您将其中一个数字四舍五入为合适的整数(我不确定四舍五入的整数是否会给您带来最佳结果,或者无论哪一个四舍五入都会给该值带来最小的百分比变化,最好-
您可以如果您非常在意,请务必尝试全部四个步骤)。一旦有了一个整数值,便可以通过找到可以乘以另一个且仍大于N的最小整数来计算另一个值,以确保适合网格中的所有矩形。

然后,您当然可以通过将高度乘以rectHeight并将wdith乘以RectWidth来将整数值改回实数。

希望一切都有意义。:)

编辑工作示例:

所需的最终网格长宽比= 1024/768(k)(假设768为宽度,而1024为高度-我一直想将其作为标准屏幕分辨率:))

“标准化”纵横比=(1024/768)*(300/109)= 3.6697(K)

因此,网格高度为sqrt(KN)= sqrt(366.97)= 19.16

网格宽度为sqrt(N / K)= 5.22

看到这一点,我们可以直观地看到宽度5和高度20将是我们的最佳匹配。其他选项可能是6和19。但这会浪费更多的空间(我认为实际上最小化宽度和高度的乘积可能是最好的计算方法,但我不确定)。

现在,这是我们在单元格中的网格大小。然后按比例将像素尺寸扩大到1500
x2180。缩小以适合768x1024意味着将两者都除以2.129(1500/768和2180/1024中的较大者)。因此,您的图片将按比例缩小2.129倍,达到141x51(ish),实际使用的总面积为705x1020,应留出最少的空白。

希望现在更有意义。我承认,我几次错误地提出了真实的价值观,所以我完全理解您为什么想要一个可行的例子。;-)

2020-07-28