如何优化矩形布局

发布于 2024-08-06 14:46:14 字数 145 浏览 4 评论 0原文

我有动态数量的等比例和大小的矩形对象,我想在屏幕上以最佳方式显示它们。我可以调整对象的大小,但需要保持比例。

我知道屏幕尺寸是多少。

如何计算将屏幕划分为的最佳行数和列数以及将对象缩放到什么尺寸?

谢谢,

杰米。

I have a dynamic number of equally proportioned and sized rectangular objects that I want to optimally display on the screen. I can resize the objects but need to maintain proportion.

I know what the screen dimensions are.

How can I calculate the optimal number of rows and columns that I will need to divide the screen in to and what size I will need to scale the objects to?

Thanks,

Jamie.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

凌乱心跳 2024-08-13 14:46:14

假设所有矩形具有相同的尺寸和方向,并且不应更改。

让我们玩!

// Proportion of the screen
// w,h width and height of your rectangles
// W,H width and height of the screen
// N number of your rectangles that you would like to fit in

// ratio
r = (w*H) / (h*W)

// This ratio is important since we can define the following relationship
// nbRows and nbColumns are what you are looking for
// nbColumns = nbRows * r (there will be problems of integers)
// we are looking for the minimum values of nbRows and nbColumns such that
// N <= nbRows * nbColumns = (nbRows ^ 2) * r
nbRows = ceil ( sqrt ( N / r ) ) // r is positive...
nbColumns = ceil ( N / nbRows )

我希望我的数学是正确的,但这离你想要的不远;)

编辑:
比率与宽度和高度之间没有太大区别...

// If ratio = w/h
r = ratio * (H/W)

// If ratio = h/w
r = H / (W * ratio)

// If r1 = (w/h) and r2 = W/H
r = r1 / r2

然后您返回使用“r”来找出行和列使用了多少。

Assuming that all rectangles have the same dimensions and orientation and that such should not be changed.

Let's play!

// Proportion of the screen
// w,h width and height of your rectangles
// W,H width and height of the screen
// N number of your rectangles that you would like to fit in

// ratio
r = (w*H) / (h*W)

// This ratio is important since we can define the following relationship
// nbRows and nbColumns are what you are looking for
// nbColumns = nbRows * r (there will be problems of integers)
// we are looking for the minimum values of nbRows and nbColumns such that
// N <= nbRows * nbColumns = (nbRows ^ 2) * r
nbRows = ceil ( sqrt ( N / r ) ) // r is positive...
nbColumns = ceil ( N / nbRows )

I hope I got my maths right, but that cannot be far from what you are looking for ;)

EDIT:
there is not much difference between having a ratio and the width and height...

// If ratio = w/h
r = ratio * (H/W)

// If ratio = h/w
r = H / (W * ratio)

// If r1 = (w/h) and r2 = W/H
r = r1 / r2

And then you're back using 'r' to find out how much rows and columns use.

泪之魂 2024-08-13 14:46:14

我喜欢的一种方法是使用面积的平方根:

r = 矩形数量

w = 显示宽度

h = 显示高度

那么,

A = (w * h) / r 是每个矩形的面积

L = sqrt(A) 是每个矩形的底长。

如果它们不是正方形,则只需相应相乘即可保持相同的比率。

做类似事情的另一种方法是只取矩形数量的平方根。这将为您提供网格的一维(即列数):

C = sqrt(n) 是网格中的列数

R = n / C code> 是行数。

请注意,其中一个必须ceiling,另一个floor,否则您将截断数字并可能会错过一行。

One way I like to do that is to use the square root of the area:

Let

r = number of rectangles

w = width of display

h = height of display

Then,

A = (w * h) / r is the area per rectangle

and

L = sqrt(A) is the base length of each rectangle.

If they are not square, then just multiply accordingly to keep the same ratio.

Another way to do a similar thing is to just take the square root of the number of rectangles. That'll give you one dimension of your grid (i.e. the number of columns):

C = sqrt(n) is the number of columns in your grid

and

R = n / C is the number of rows.

Note that one of these will have to ceiling and the other floor otherwise you will truncate numbers and might miss a row.

許願樹丅啲祈禱 2024-08-13 14:46:14

杰米,我将“最佳行数和列数”解释为“有多少行和列将提供最大的矩形,与所需的比例和屏幕尺寸一致”。这是一种解释该解释的简单方法。

每个可能的选择(矩形的行数和列数)都会产生指定比例的矩形的最大可能尺寸。循环可能的选择并计算结果大小,在可能的解决方案空间上实现简单的线性搜索。下面是执行此操作的一些代码,使用 480 x 640 的示例屏幕和 3 x 5 比例的矩形。

def min (a, b)
  a < b ? a : b
end

screenh, screenw = 480, 640
recth, rectw = 3.0, 5.0
ratio = recth / rectw

puts ratio

nrect = 14

(1..nrect).each do |nhigh|
  nwide = ((nrect + nhigh - 1) / nhigh).truncate
  maxh, maxw = (screenh / nhigh).truncate, (screenw / nwide).truncate
  relh, relw = (maxw * ratio).truncate, (maxh / ratio).truncate
  acth, actw = min(maxh, relh), min(maxw, relw)
  area = acth * actw
  puts ([nhigh, nwide, maxh, maxw, relh, relw, acth, actw, area].join("\t"))
end

运行该代码会提供以下跟踪:

1 14 480 45 27 800 27 45 1215
2 7 240 91 54 400 54 91 4914
3 5 160 128 76 266 76 128 9728
4 4 120 160 96 200 96 160 15360
5 3 96 213 127 160 96 160 15360
6 3 80 213 127 133 80 133 10640
7 2 68 320 192 113 68 113 7684
8 2 60 320 192 100 60 100 6000
9 2 53 320 192 88 53 88 4664
10 2 48 320 192 80 48 80 3840
11 2 43 320 192 71 43 71 3053
12 2 40 320 192 66 40 66 2640
13 2 36 320 192 60 36 60 2160
14 1 34 640 384 56 34 56 1904

由此可以清楚地看出,4x4 或 5x3 布局将生成最大的矩形。同样清楚的是,矩形大小(作为行数的函数)在极端处最差(最小),在中间点处最佳(最大)。假设矩形的数量不多,您可以简单地用您选择的语言编写上面的计算代码,但一旦结果面积在上升到最大值后开始减少,就立即退出。

这是一个快速而肮脏的(但我希望,相当明显的)解决方案。如果矩形的数量变得足够大,您可以通过多种方式调整性能:

  • 使用更复杂的搜索算法(划分空间并递归搜索最佳部分)
  • 如果矩形的数量在程序期间不断增长,则 ,保留之前的结果并仅搜索附近的解,
  • 应用一些微积分以获得更快、更精确但不太明显的公式。

Jamie, I interpreted "optimal number of rows and columns" to mean "how many rows and columns will provide the largest rectangles, consistent with the required proportions and screen size". Here's a simple approach for that interpretation.

Each possible choice (number of rows and columns of rectangles) results in a maximum possible size of rectangle for the specified proportions. Looping over the possible choices and computing the resulting size implements a simple linear search over the space of possible solutions. Here's a bit of code that does that, using an example screen of 480 x 640 and rectangles in a 3 x 5 proportion.

def min (a, b)
  a < b ? a : b
end

screenh, screenw = 480, 640
recth, rectw = 3.0, 5.0
ratio = recth / rectw

puts ratio

nrect = 14

(1..nrect).each do |nhigh|
  nwide = ((nrect + nhigh - 1) / nhigh).truncate
  maxh, maxw = (screenh / nhigh).truncate, (screenw / nwide).truncate
  relh, relw = (maxw * ratio).truncate, (maxh / ratio).truncate
  acth, actw = min(maxh, relh), min(maxw, relw)
  area = acth * actw
  puts ([nhigh, nwide, maxh, maxw, relh, relw, acth, actw, area].join("\t"))
end

Running that code provides the following trace:

1 14 480 45 27 800 27 45 1215
2 7 240 91 54 400 54 91 4914
3 5 160 128 76 266 76 128 9728
4 4 120 160 96 200 96 160 15360
5 3 96 213 127 160 96 160 15360
6 3 80 213 127 133 80 133 10640
7 2 68 320 192 113 68 113 7684
8 2 60 320 192 100 60 100 6000
9 2 53 320 192 88 53 88 4664
10 2 48 320 192 80 48 80 3840
11 2 43 320 192 71 43 71 3053
12 2 40 320 192 66 40 66 2640
13 2 36 320 192 60 36 60 2160
14 1 34 640 384 56 34 56 1904

From this, it's clear that either a 4x4 or 5x3 layout will produce the largest rectangles. It's also clear that the rectangle size (as a function of row count) is worst (smallest) at the extremes and best (largest) at an intermediate point. Assuming that the number of rectangles is modest, you could simply code the calculation above in your language of choice, but bail out as soon as the resulting area starts to decrease after rising to a maximum.

That's a quick and dirty (but, I hope, fairly obvious) solution. If the number of rectangles became large enough to bother, you could tweak for performance in a variety of ways:

  • use a more sophisticated search algorithm (partition the space and recursively search the best segment),
  • if the number of rectangles is growing during the program, keep the previous result and only search nearby solutions,
  • apply a bit of calculus to get a faster, precise, but less obvious formula.
雨后彩虹 2024-08-13 14:46:14

这几乎与肯尼思的问题完全一样。他还将其写在他的博客上

如果在一维上缩放比例以便包装正方形,则会出现同样的问题。

This is almost exactly like kenneth's question here on SO. He also wrote it up on his blog.

If you scale the proportions in one dimension so that you are packing squares, it becomes the same problem.

拥抱影子 2024-08-13 14:46:14

您提到的行和列表明您设想将矩形排列在网格中,可能有一些空格(例如底行的一些)未填充。假设情况是这样:

假设您缩放对象,使得(数量未知)n 的对象适合整个屏幕。现在

objectScale=screenWidth/(n*objectWidth)

假设有 N 个对象,因此将有

nRows = ceil(N/n)

几行对象(其中 ceil 是 Ceiling 函数),它将占据

nRows*objectScale*objectHeight

垂直高度。我们需要找到n,并选择最小的n,使得该距离小于screenHeight

由于存在上限函数,n 的简单数学表达式变得更加棘手。如果列数相当小,找到 n 的最简单方法可能就是循环增加 n 直到满足不等式。

编辑:我们可以从 for n 的上限开始循环

floor(sqrt(N*objectHeight*screenWidth/(screenHeight*objectWidth)))

,然后向下计算:然后在 O(sqrt(N)) 中找到解决方案。 O(1) 解决方案是假设

nRows = N/n + 1

或 采用

n=ceil(sqrt(N*objectHeight*screenWidth/(screenHeight*objectWidth)))

(Matthieu M. 的解决方案),但这些解决方案的缺点是 n 的值可能不是最优的。

N=0N=1 且对象的长宽比满足 objectHeight/objectWidth > 时,会出现边框情况。 screenHeight/screenWidth - 这两个都很容易处理。

Your mention of rows and columns suggests that you envisaged arranging the rectangles in a grid, possibly with a few spaces (e.g. some of the bottom row) unfilled. Assuming this is the case:

Suppose you scale the objects such that (an as-yet unknown number) n of them fit across the screen. Then

objectScale=screenWidth/(n*objectWidth)

Now suppose there are N objects, so there will be

nRows = ceil(N/n)

rows of objects (where ceil is the Ceiling function), which will take up

nRows*objectScale*objectHeight

of vertical height. We need to find n, and want to choose the smallest n such that this distance is smaller than screenHeight.

A simple mathematical expression for n is made trickier by the presence of the ceiling function. If the number of columns is going to be fairly small, probably the easiest way to find n is just to loop through increasing n until the inequality is satisfied.

Edit: We can start the loop with the upper bound of

floor(sqrt(N*objectHeight*screenWidth/(screenHeight*objectWidth)))

for n, and work down: the solution is then found in O(sqrt(N)). An O(1) solution is to assume that

nRows = N/n + 1

or to take

n=ceil(sqrt(N*objectHeight*screenWidth/(screenHeight*objectWidth)))

(the solution of Matthieu M.) but these have the disadvantage that the value of n may not be optimal.

Border cases occur when N=0, and when N=1 and the aspect ratio of the objects is such that objectHeight/objectWidth > screenHeight/screenWidth - both of these are easy to deal with.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文