我需要在给定容器中分发“n”个图像。如果容器的纵横比是横向,纵向或正方形,它应该优化空间。目的是使图像尽可能大,并且所有图像都具有相同的可用空间。为此,我计划创建一个网格,但我需要知道根据容器的纵横比,它必须有多少列和多少行。
我看了this question,但这并不是我需要的。
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};}
我真的很感激这里的一些帮助。
提前致谢,
迭
答案 0 :(得分:2)
我找到了一个解决方案,它可能不是最好的算法,但它至少可以用于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;
}
}
}
}
}
答案 1 :(得分:1)
以下是JavaScript中的内容。这对你有用吗?
var height = 30, //pixels
width = 30, //pixels
n = 8,
cellSideLength = Math.floor(Math.sqrt(height * width / n)),
targetColumns = Math.floor(width / cellSideLength) == width / cellSideLength
? width/cellSideLength
: Math.floor(width / cellSideLength) + 1,
cellSideLengthTemp = cellSideLength
targetColumns = Math.min(targetColumns,n)
while (width / cellSideLengthTemp < targetColumns)
cellSideLengthTemp-- //decrease by one pixel
while (Math.floor(height / cellSideLengthTemp) * targetColumns < n)
cellSideLengthTemp-- //decrease by one pixel
var numColumns = Math.floor(width / cellSideLengthTemp),
numRows = 1
while (numColumns * numRows < n)
numRows++
console.log(numColumns,numRows,cellSideLengthTemp,cellSideLength)
答案 2 :(得分:0)
假设单元格是正方形,您可以简单地执行此操作(伪代码):
float proportion = width / height;
int columns = min(cellCount, (int)round(sqrt(proportion * cellCount)));
int rows = (cellCount + columns - 1) / columns; // int division with rounding up