Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resizing N # of squares to be as big as possible while still fitting into box of X by Y dimensions. (Thumbnails!)

I have N squares. I have a Rectangular box. I want all the squares to fit in the box. I want the squares to be as large as possible.

How do I calculate the largest size for the squares such that they all fit in the box?

This is for thumbnails in a thumbnail gallery.

int function thumbnailSize(
    iItems, // The number of items to fit.
    iWidth, // The width of the container.
    iHeight, // The height of the container.
    iMin // The smallest an item can be.
)
{
    // if there are no items we don't care how big they are!    
    if (iItems = 0) return 0;

    // Max size is whichever dimension is smaller, height or width.
    iDimension = (iWidth min iHeight);

    // Add .49 so that we always round up, even if the square root
    // is something like 1.2.  If the square root is whole (1, 4, etc..)
    // then it won't round up.
    iSquare = (round(sqrt(iItems) + 0.49));

    // If we arrange our items in a square pattern we have the same
    // number of rows and columns, so we can just divide by the number
    // iSquare, because iSquare = iRows = iColumns.
    iSize = (iDimension / iSquare);

    // Don't use a size smaller than the minimum.
    iSize = (iSize max iMin);

    return iSize;
 }

This code currently works OK. The idea behind it is to take the smallest dimension of the rectangular container, pretend the container is a square of that dimension, and then assume we have an equal number of rows and columns, just enough to fit iItems squares inside.

This function works great if the container is mostly squarish. If you have a long rectangle, though, the thumbnails come out smaller than they could be. For instance, if my rectangle is 100 x 300, and I have three thumbnails, it should return 100, but instead returns 33.

like image 495
Jake Avatar asked Oct 15 '09 22:10

Jake


1 Answers

Probably not optimal (if it works which I haven't tried), but I think better than you current approach :

w: width of rectangle

h: height of rectangle

n: number of images

a = w*h : area of the rectangle.

ia = a/n max area of an image in the ideal case.

il = sqrt(ia) max length of an image in the ideal case.

nw = round_up(w/il): number of images you need to stack on top of each other.

nh = round_up(h/il): number of images you need to stack next to each other.

l = min(w/nw, w/nh) : length of the images to use.

like image 108
Carsten Avatar answered Sep 18 '22 11:09

Carsten