How large rectangles fit on canvas I have images whose side ratios are known, and the number of images is known. I have canvas whose measurements are known. I need to know what's the optimal length of images sides so that all my images would fit on canvas and maximum area is used.
All images are of the same size. And images should be placed correctly for viewing. (not on a side that would make image horizont be in vertical angle.)
I put the question under discrete-mathematics, let me know if it's in a wrong place.
Thanks. :)
 A: I found a neat implementation to a similar question from Neptilo. It didn't work for rectangles though, only squares. So I applied the idea from mckeed to normalise the rectangle and then follow the algorithm for squares.
The result is the fitToContainer()  function. Give it the number of rectangles to fit n, the containerWidth and containerHeight and the original itemWidth and itemHeight. In case items have no original width and height, use itemWidth and itemHeight to specify the desired ratio of the items.
For example fitToContainer(10, 1920, 1080, 16, 9) results in {nrows: 4, ncols: 3, itemWidth: 480, itemHeight: 270}, so four columns and 3 rows of 480 x 270 (pixels, or whatever the unit is).
And to fit 10 squares in the same example area of 1920x1080 you could call fitToContainer(10, 1920, 1080, 1, 1) resulting in {nrows: 2, ncols: 5, itemWidth: 384, itemHeight: 384}.
function fitToContainer(n, containerWidth, containerHeight, itemWidth, itemHeight) {
    // We're not necessarily dealing with squares but rectangles (itemWidth x itemHeight),
    // temporarily compensate the containerWidth to handle as rectangles
    containerWidth = containerWidth * itemHeight / itemWidth;
    // Compute number of rows and columns, and cell size
    var ratio = containerWidth / containerHeight;
    var ncols_float = Math.sqrt(n * ratio);
    var nrows_float = n / ncols_float;

    // Find best option filling the whole height
    var nrows1 = Math.ceil(nrows_float);
    var ncols1 = Math.ceil(n / nrows1);
    while (nrows1 * ratio < ncols1) {
        nrows1++;
        ncols1 = Math.ceil(n / nrows1);
    }
    var cell_size1 = containerHeight / nrows1;

    // Find best option filling the whole width
    var ncols2 = Math.ceil(ncols_float);
    var nrows2 = Math.ceil(n / ncols2);
    while (ncols2 < nrows2 * ratio) {
        ncols2++;
        nrows2 = Math.ceil(n / ncols2);
    }
    var cell_size2 = containerWidth / ncols2;

    // Find the best values
    var nrows, ncols, cell_size;
    if (cell_size1 < cell_size2) {
        nrows = nrows2;
        ncols = ncols2;
        cell_size = cell_size2;
    } else {
        nrows = nrows1;
        ncols = ncols1;
        cell_size = cell_size1;
    }

    // Undo compensation on width, to make squares into desired ratio
    itemWidth = cell_size * itemWidth / itemHeight;
    itemHeight = cell_size;
    return { nrows: nrows, ncols: ncols, itemWidth: itemWidth, itemHeight: itemHeight }
}

A: Let's say you want to resize an image of size $l_1 \times w_1$ in a canvas sized $L \times W$. Then your scale factor to maximize the resized image allows one of its dimensions to reach the canvas dimension.
Thus we find a scale factor $s=Min(L/l_1,W/w_1)$ and a resized image of dimensions $l_2 \times w_2 = l_1 \cdot s \times w_1 \cdot s$.


*

*If the length to width ratio of the image is larger than the canvas, then the length dimension will be filled $l_2 = l_1 \cdot s = l_1 \cdot L/l_1 = L$.

*Otherwise, the width dimension will be filled $w_2 = w_1 \cdot s = w_1 \cdot W/w_1 = W$.


For multiple images aligned in a M*N rectangular fashion, swap $l_1$ and $w_1$ for $M \cdot l_1$ and $N \cdot w_1$. For any other adjustment, find the dimensions of the whole merged  group and apply the same rules as if it was a single (bigger) image.
A: This link had (Almost) the answer:
https://stackoverflow.com/questions/10643129/split-screen-based-on-number-of-items-and-screen-ratio

// Set this to the desired x-to-y ratio. const preferred_ratio = 1.2;
function calc_cols_rows(In: screen, In: num_items, Out: num_rows, Out:
num_cols) {   desired_aspect = (screen.width / screen.height) /
preferred_ratio;
// Calculate the number of rows that is closest to the desired
aspect:
num_rows = round(sqrt(num_items / desired_aspect));
// Calculate the required number of columns:
num_cols =
ceil(num_items / num_rows); }

