algorithms = ({
"Minimum rows × cols": (containerAspectRatio, facetAspectRatio, n) => {
const ratio = containerAspectRatio / facetAspectRatio;
const cols = Math.min(Math.sqrt(n * ratio), n);
const rows = Math.min(n / cols, n);
const rows_ceil = Math.ceil(rows);
const cols_ceil = Math.ceil(cols);
const rows_floor = Math.floor(rows);
const cols_floor = Math.floor(cols);
if (rows_ceil * cols_floor >= n) {
return {
rows: rows_ceil,
cols: cols_floor
};
} else if (rows_floor * cols_ceil >= n) {
return {
rows: rows_floor,
cols: cols_ceil
};
} else {
return {
rows: rows_ceil,
cols: cols_ceil
};
}
},
// const rows_ceil = Math.ceil(rows)
// const cols_ceil = Math.ceil(cols)
// const rows_floor = Math.floor(rows)
// const cols_floor = Math.floor(cols)
// if (rows_ceil * cols_floor >= n) {
// return {
// rows: rows_ceil,
// cols: cols_floor
// }
// } else {
// return {
// rows: rows_ceil,
// cols: cols_ceil
// }
// }
// },
"Round col, then derive row": (containerAspectRatio, facetAspectRatio, n) => {
const ratio = facetAspectRatio / containerAspectRatio;
const rows_initial = Math.min(Math.sqrt(n * ratio), n);
const cols_initial = Math.min(n / rows_initial, n);
const cols = Math.round(cols_initial);
const rows = Math.ceil(n / cols);
return {
rows,
cols
};
},
"✅ Round col, then derive row, remove extra columns": (
containerAspectRatio,
idealAspectRatio,
n
) => {
const ratio = containerAspectRatio / idealAspectRatio;
// Prefer vertical grid for count=2.
if (count === 2 && ratio < 2) return { rows: 2, columns: 1 };
// Otherwise, optimize for closest to the ideal aspect ratio.
const initialColumns = Math.min(
Math.round(Math.sqrt(count * ratio)),
count
);
const rows = Math.ceil(count / initialColumns);
// Remove extra columns if we can fit everything in fewer.
// This will result in wider aspect ratios than ideal, which is ok.
const columns = Math.ceil(count / rows);
return {
rows,
cols: columns
};
},
"Floor col, then derive row": (containerAspectRatio, facetAspectRatio, n) => {
const ratio = facetAspectRatio / containerAspectRatio;
const rows = Math.min(Math.sqrt(n * ratio), n);
const cols = Math.min(n / rows, n);
const cols_temp = Math.floor(cols);
const rows_temp = Math.ceil(n / cols_temp);
return {
rows: rows_temp,
cols: cols_temp
};
},
"Round row, then derive col": (containerAspectRatio, facetAspectRatio, n) => {
const ratio = facetAspectRatio / containerAspectRatio;
const rows = Math.min(Math.sqrt(n * ratio), n);
const cols = Math.min(n / rows, n);
const rows_temp = Math.round(rows);
const cols_temp = Math.ceil(n / rows_temp);
return {
rows: rows_temp,
cols: cols_temp
};
}
// // Adapted from: https://math.stackexchange.com/a/2570649
// "StackOverflow #1": (containerAspectRatio, facetAspectRatio, n) => {
// const ratio = containerAspectRatio / facetAspectRatio;
// const cols = Math.sqrt(n * ratio);
// const rows = n / cols;
// // Find best option filling the whole height
// let rows1 = Math.ceil(rows);
// let cols1 = Math.ceil(n / rows1);
// while (rows1 * ratio < cols1) {
// rows1++;
// cols1 = Math.ceil(n / rows1);
// }
// const cellSize1 = 1 / rows1;
// // Find best option filling the whole width
// let cols2 = Math.ceil(cols);
// let rows2 = Math.ceil(n / cols2);
// while (cols2 < rows2 * ratio) {
// cols2++;
// rows2 = Math.ceil(n / cols2);
// }
// const cellSize2 = containerAspectRatio / cols2;
// // Find the best values
// if (cellSize1 < cellSize2) {
// return {
// rows: rows2,
// cols: cols2,
// };
// } else {
// return {
// rows: rows1,
// cols: cols1,
// };
// }
// },
// "StackOverflow #2": (containerAspectRatio, facetAspectRatio, n) => {
// const x = containerAspectRatio / facetAspectRatio;
// const y = 1;
// let sx, sy;
// const px = Math.ceil(Math.sqrt((n * x) / y));
// if (Math.floor((px * y) / x) * px < n) {
// sx = y / Math.ceil((px * y) / x);
// } else {
// sx = x / px;
// }
// var py = Math.ceil(Math.sqrt((n * y) / x));
// if (Math.floor((py * x) / y) * py < n) {
// sy = x / Math.ceil((x * py) / y);
// } else {
// sy = y / py;
// }
// const size = Math.max(sx, sy);
// const cols = Math.ceil(containerAspectRatio / (size * facetAspectRatio));
// const rows = Math.ceil(n / cols);
// return {
// cols,
// rows,
// };
// },
})