Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 如何优化矩形的布局_Algorithm_Math_Layout_Screen_Rectangles - Fatal编程技术网

Algorithm 如何优化矩形的布局

Algorithm 如何优化矩形的布局,algorithm,math,layout,screen,rectangles,Algorithm,Math,Layout,Screen,Rectangles,我有一个动态的数量相等的比例和大小的矩形对象,我想最好地显示在屏幕上。我可以调整对象的大小,但需要保持比例 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)

我有一个动态的数量相等的比例和大小的矩形对象,我想最好地显示在屏幕上。我可以调整对象的大小,但需要保持比例

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
我知道屏幕尺寸是多少

如何计算屏幕分割所需的最佳行数和列数,以及缩放对象所需的大小

谢谢


Jamie.

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

假设您缩放对象,使其(一个未知数字)
n
适合整个屏幕。然后

objectScale=screenWidth/(n*objectWidth)
现在假设有N个对象,那么将有

nRows = ceil(N/n)
对象行(其中ceil是

nRows*objectScale*objectHeight
垂直高度的。我们需要找到
n
,并希望选择最小的
n
,以便此距离小于
屏幕高度

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

编辑:我们可以使用

floor(sqrt(N*objectHeight*screenWidth/(screenHeight*objectWidth)))
对于n,向下展开:然后在O(sqrt(n))中找到解。O(1)解是假设

nRows = N/n + 1
或采取

n=ceil(sqrt(N*objectHeight*screenWidth/(screenHeight*objectWidth)))
(Matthieu M.的解决方案)但这些方法的缺点是
n
的值可能不是最佳值


N=0
N=1
且对象的纵横比为
objectHeight/objectWidth>screenHeight/screenWidth
时,会出现边界情况-这两种情况都很容易处理。

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

r=矩形数

w=显示宽度

h=显示高度

那么

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

L=sqrt(A)
是每个矩形的基本长度

如果它们不是平方的,那么只需相应地相乘以保持相同的比率

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

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

R=n/C
是行数


请注意,其中一个必须是
天花板
,另一个是
地板
,否则您将截断数字并可能丢失一行。

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

我们来玩吧

// 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 )
然后再使用“r”来找出行和列的使用量。

Jamie,我将“最佳行和列数”解释为“有多少行和列将提供最大的矩形,与所需的比例和屏幕大小一致”。这里有一个简单的解释方法

每个可能的选择(矩形的行数和列数)都会产生指定比例的最大可能矩形大小。在可能的选择上循环并计算结果大小,在可能的解空间上实现简单的线性搜索。这里有一些代码可以做到这一点,使用一个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
由此可知,无论是4x4还是5x3布局都会产生最大的矩形。同样清楚的是,矩形大小(作为行数的函数)在极值处最差(最小),在中间点处最好(最大)。假设矩形的数量适中,您可以简单地用您选择的语言编写上面的计算代码,但一旦生成的面积在上升到最大值后开始减少,就可以退出

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

  • 使用更复杂的搜索算法(划分空间并递归搜索最佳分段)
  • 如果在编程过程中矩形的数量不断增加,请保留以前的结果,只搜索附近的解决方案
  • 应用一点微积分,得到一个更快,精确,但不太明显的公式

    • 这几乎和这里一模一样。他也


      如果您在一维中缩放比例,以便填充正方形,则会出现相同的问题。

      它们是否都具有相同的大小和方向?你能转动它们吗?或者它们应该保持比例和方向?我很确定这是一个NP完全问题。@John:这个NPC怎么样?我认为它在最坏的情况下是线性的(在可能的列数上迭代一次,即[1,N])。问题是如何优化计算'N'。当然,如果我知道要在屏幕上放置多少个对象,那么就很容易计算出其他所有内容,但这是个未知数。问题是如何计算最佳“n”,从而计算所需的行数,然后计算得到的对象宽度和高度。。。干杯,杰米。绝对-看编辑:我不认为最佳n的解析表达式是可能的,但可以最小化搜索。这篇博客文章很棒,而且对于一致的布局更有用。Kenneth问题中的答案对于理论最大化(即旋转正方形以最小化矩形中的空间)有更有用的答案。
      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