如何水平分布不同大小的矩形?

时间:2016-07-29 08:16:39

标签: javascript algorithm geometry

我有一组不同大小的矩形:

enter image description here

所有矩形都在Y方向上受约束,即Y坐标是固定的,它们只能沿X轴移动。 现在,我想水平排列所有这些具有相等分布间距的矩形,但其中一些(图片中的灰色矩形)受左右邻居(红色矩形)约束,但也受下面矩形的约束。以上也是。

编辑: 矩形的初始位置按行顺序定义。 此外,在我的第一次实现尝试中,我还在每行中存储了垂直矩形的存在,这些矩形重叠了两行或更多行,如下所示:

Row 1: {id:1,w:15,h:10},{id:2,w:10,h:40},{id:3,w:10,h:40},{id:4,w:20,h:10}
Row 2: {id:2,w:10,h:40},{id:5,w:10,h:40},{id:3,w:10,h:40},{id:6,w:10,h:10},{id:7,w:10,h:10}
Row 3: {id:8,w:10,h:10},{id:9,w:18,h:10},{id:5,w:10,h:40},{id:10,w:10,h:10}

我正在搜索一个算法来水平分布所有这些矩形,这样每个矩形的左右间距与最近的相同,就像在图片中一样。

编辑2: 任何提示如何处理更高复杂性的提示也将受到赞赏:

More graphs

1 个答案:

答案 0 :(得分:2)

使用最左边的坐标从左到右对矩形进行排序,如下图所示:

rectangles

然后,从左到右迭代每个矩形,看看它们左边的哪些矩形与它们垂直重叠(即如果你向左移动它们,它们会撞到哪个矩形)。

  

A和B到达左窗口边缘而不会碰到任何其他矩形   C碰到了A.
  D碰到B.   E撞到A,C和D.   F碰到B,D和E.   G撞到D,E和F.
  H撞到A,C和E.   我碰到了B,D和F.   J碰到D,E,F和G.

使用此信息构建图形,如下所示。当矩形碰到几个其他矩形时,例如, E碰撞到A,C和D,并且这些矩形本身是同一分支的一部分,例如, A和C,然后只将它连接到最右边的矩形,即矩形C.

rectangle graph

然后,在图表中存储每个矩形的宽度(以像素为单位)。然后我们将尝试找到边缘的权重X,它表示矩形之间的空间宽度。

为此,我们需要在图表中找到许多路径。首先,我们搜索最长的路径,即具有最多矩形的路径,而不考虑它们的宽度;在示例中:

  

左窗口边缘→A→C→E→F→G→J
  左窗口边缘→B→D→E→F→G→J

然后我们检查这些路径中哪一个具有最大的组合宽度:

  

左窗口边缘→A→C→E→F→G→J = 240

然后我们查看较短的路径,看看它们是否有更大的宽度:

  

左窗口边缘→A→C→E→F→I = 230
  左窗口边缘→B→D→E→F→I = 220
  左窗口边缘→A→C→E→H = 168
  左窗边→B→D→E→H = 158

在该示例中,没有较短的路径具有更大的宽度。如果他们中的一些人做了,我们也必须考虑每个长度的最宽路径。事实上,我们只需看看路径:

  

左窗口边缘→A→C→E→F→G→J = 240

将此路径连接到右侧窗口边缘,使其具有额外边缘;现在有7个宽度为X的边缘。矩形的组合宽度是240个像素,所以如果窗口是例如450像素宽,然后X =(450-240)/ 7 = 30像素。 如果需要考虑多个路径,则需要采用X的最小结果。

rectangle graph 2

路径中具有最小X结果的矩形将在它们之间具有正好X个像素的空间;其他矩形有一些摆动空间。您可以输入X作为图形中最长路径边缘的权重,然后使用图形进一步计算其他矩形的相等间距。或者你可以把它们放在离他们左边或右边邻居的距离X处。

对于更复杂的情况,假设在示例矩形中,我是90像素宽,矩形H是120像素宽。这些将是路径:

  

6个矩形:
  左窗口边缘→A→C→E→F→G→J = 240
  左窗口边缘→B→D→E→F→G→J = 230

     

5个矩形:
  左窗口边缘→A→C→E→F→I = 254
  左窗口边缘→B→D→E→F→I = 244

     

4个矩形:
  左窗口边缘→A→C→E→H = 250
  左窗口边缘→B→D→E→H = 240

然后要考虑的路径是:

  

左窗口边缘→A→C→E→F→G→J = 240

因为它是具有最多(6)个矩形的最宽路径,并且:

  

左窗口边缘→A→C→E→F→I = 254

因为它是具有5个矩形的最宽的路径,并且比6个矩形路径宽。

(最宽的4个矩形路径比6个矩形路径宽,但不比5个矩形路径宽,所以可以忽略它。)

这给出了条件:

  

240 + 7×X = W
  254 + 6×X = W

因此,对于窗口宽度290,这将给出:

  

240 + 7×X = 290→X = 7
  254 + 6×X = 290→X = 6

因此,路径A→C→E→F→I确定空间的宽度,为6像素。

但是对于窗口宽度390,这将给出:

  

240 + 7×X = 390→X = 21
  254 + 6×X = 390→X = 22

所以现在路径A→C→E→F→G→J确定空间的宽度,为21像素。