algorithm - 有效地计算单位网格中矩形的位置

标签 algorithm layout grid-layout

我正在研究一种特定的布局算法,以在基于单元的网格中显示照片。所需的行为是将每张照片逐行放置在下一个可用空间中。

animation of what the algorithm should achieve

由于很容易有上千张照片需要一次计算位置,因此效率非常重要。

这个问题可能已经用现有的算法解决了吗? 如果不是,我怎样才能尽可能高效?

编辑 关于定位: 我现在基本上在做的是逐个单元格地迭代网格的每一行,直到找到适合元素的空间。这就是 4 放在 2 旁边的原因。

最佳答案

如何按宽度保留下一个可用行的列表?最初,下一个可用行列表如下所示:

(0,0,0,0,0)

添加第一张照片后,它看起来像

(0,0,0,0,1)

然后

(0,0,0,2,2)

然后

(0,0,0,3,3)

然后

(1,1,1,4,4)

最后的照片不会改变列表。

这可能是高效的,因为您只维护一个小列表,在每次迭代时更新一点点(相对于每次搜索整个空间。它变得有点复杂 - 可能有一种情况(有一张高大的照片)如果名义上的下一个可用行不起作用,那么您可以默认使用现有方法。但总的来说,我认为这应该会节省相当多的时间,但代价是增加了一点复杂性。

更新 响应@matteok 对 coordinateForPhoto(width, height) 方法的请求:

假设我将该数组称为“nextAvailableRowByWidth”。

public Coordinate coordinateForPhoto(width, height) {
    int rowIndex = nextAvailableRowByWidth[width + 1]; // because arrays are zero-indexed
    int[] row = space[rowIndex]
    int column = findConsecutiveEmptySpace(width, row);
    for (int i = 1; i < height; i++) {
        if (!consecutiveEmptySpaceExists(width, space[i], column)) {
            return null;
            // return and fall back on the slow method, starting at rowIndex
        }
    }
    // now either you broke out and are solving some other way,
    // or your starting point is rowIndex, column.  Done.
    return new Coordinate(rowIndex, column);
}

更新#2 响应@matteok 关于如何更新 nextAvailableRowByWidth 数组的请求:

好的,所以你刚刚在第 R 行放置了一张高 H 宽 W 的新照片。数组中小于 R 的任何元素都不会改变(因为这个改变不会影响他们的行,所以如果在放置照片之前该行中有 3 个连续的可用空间,则之后仍然有 3 个连续的可用空间)。范围 (R, R+H) 中的每个元素都需要检查,因为它可能已受到影响。让我们假设一个方法 maxConsecutiveBlocksInRow() - 因为它很容易编写,对吧?

public void updateAvailableAfterPlacing(int W, int H, int R) {
    for (int i = 0; i < nextAvailableRowByWidth.length; i++) {
        if (nextAvailableRowByWidth[i] < R) {
            continue;
        }
        int r = R;
        while (maxConsecutiveBlocksInRow(r) < i + 1) {
            r++;
        }
        nextAvailableRowByWidth[i] = r;
    }
}

我认为应该这样做。

关于algorithm - 有效地计算单位网格中矩形的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31248532/

相关文章:

java - JLabel 未在 JPanel 内截断

java - 使 GridLayout 的一列水平填充

twitter-bootstrap - 如果运行良好,跨度在 Bootstrap 中添加到父级不起作用

python - 在列表中寻找下降。这可以在 O(log n) 中完成吗?

css - IE奇怪的边框

android - 是否可以在 android 中定义随配置变化的 XML 常量

css - 我的博客上的 960gs 和 Internet Explorer 问题

performance - Raytracer - 寻找下一个光线交点的标准方法是什么,它们的优缺点是什么

string - 查找可以派生字符串的不同路径的数量

sql - 间隔表中的间隔