根据可用空间计算所需的列数和行数

Die*_*gun 5 java algorithm

我需要在给定的容器中分发"n"个图像.如果容器的纵横比是横向,纵向或正方形,它应该优化空间.目的是使图像尽可能大,并且所有图像都具有相同的可用空间.为此,我计划创建一个网格,但我需要知道根据容器的纵横比,它必须有多少列和多少行.

我看了一下这个问题,但这并不是我需要的.

这个n = 8的图像应该澄清一下:

计算列和行

如果容器是垂直的,则需要4行和2列,如果容器是正方形,则需要3行3列,如果容器是水平的,则需要2行4列.

我正在写一个函数,但我陷入了中间:

private int[] calculateRowsAndColumnsNeeded(int numberOfImages, Dimension containerSize){
int numberOfColumns = 0;
int numberOfRows = 0;

int containerArea = containerSize.height * containerSize.width;
float singleCellArea = containerArea / numberOfImages;
double cellSideLength = Math.sqrt(singleCellArea);

// What to do with cellSideLength to get the right number of columns and rows?

return new int[]{numberOfColumns, numberOfRows};}
Run Code Online (Sandbox Code Playgroud)

我真的很感激这里的一些帮助.

提前致谢,

迭戈

Die*_*gun 3

我找到了一个解决方案,它可能不是最好的算法,但它至少适用于 1 - 20 个元素,这正是我所需要的。我没有进一步测试。如果以后找到方法我会改进的。

    private static int[] calculateRowsAndColumnsNeeded(int numberOfImages, Dimension containerSize){
    int colsAttempt = 0;
    int rowsAttempt = 0;
    // Calculate the length of one side from a single cell
    int containerArea = containerSize.height * containerSize.width;
    float singleCellArea = containerArea / numberOfImages;
    double cellSideLength = Math.sqrt(singleCellArea);

    colsAttempt = (int) Math.floor(containerSize.width / cellSideLength);
    rowsAttempt =  (int) Math.floor(containerSize.height / cellSideLength);

    if (colsAttempt * rowsAttempt >= numberOfImages){

        return new int[]{rowsAttempt, colsAttempt};

    }
    // If the container is a square or bigger horizontally than vertically
    else if (containerSize.height <= containerSize.width){

        colsAttempt = (int) Math.ceil(containerSize.width / cellSideLength);
        rowsAttempt =  (int) Math.floor(containerSize.height / cellSideLength);

        if (colsAttempt * rowsAttempt >= numberOfImages){
            // 
            return new int[]{rowsAttempt, colsAttempt};

        }else{

            colsAttempt = (int) Math.floor(containerSize.width / cellSideLength);
            rowsAttempt =  (int) Math.ceil(containerSize.height / cellSideLength);

            if (colsAttempt * rowsAttempt >= numberOfImages){
                return new int[]{rowsAttempt, colsAttempt};
            }else{
                colsAttempt = (int) Math.ceil(containerSize.width / cellSideLength);
                rowsAttempt =  (int) Math.ceil(containerSize.height / cellSideLength);

                if (colsAttempt * rowsAttempt >= numberOfImages){
                    return new int[]{rowsAttempt, colsAttempt};
                }else{
                    return null;
                }
            }
        }
    } 
    // If the container is bigger vertically than horizontally
    else {

        colsAttempt = (int) Math.floor(containerSize.width / cellSideLength);
        rowsAttempt =  (int) Math.ceil(containerSize.height / cellSideLength);

        if (colsAttempt * rowsAttempt >= numberOfImages){
            // 
            return new int[]{rowsAttempt, colsAttempt};

        }else{

            colsAttempt = (int) Math.ceil(containerSize.width / cellSideLength);
            rowsAttempt =  (int) Math.floor(containerSize.height / cellSideLength);

            if (colsAttempt * rowsAttempt >= numberOfImages){
                return new int[]{rowsAttempt, colsAttempt};
            }else{
                colsAttempt = (int) Math.ceil(containerSize.width / cellSideLength);
                rowsAttempt =  (int) Math.ceil(containerSize.height / cellSideLength);

                if (colsAttempt * rowsAttempt >= numberOfImages){
                    return new int[]{rowsAttempt, colsAttempt};
                }else{
                    return null;
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)