# Is there an algorithm to determine if one or two images can be presented on screen? (singe page vs double page)

Given a known number of images with the same width to height ratio and dimensions, is there an algorithm that determines the best way to present them in a screen whose resolution may vary? Aka arrange them single page or double page.

For example, to determine if you can present two images on the screen or, given the width/height, to "detect" that only one would look better. To see if it's better to have them fit on width, with some blank space above and/or below them, or to fit on height, with blank space on the left/right.

I have made some attempts to determine such an algorithm of my own, but I'm not completely satisfied and I was hoping there might be a better solution or maybe some advices.

Unfortunately, it's not as simple as "width > height => two images otherwise one image", as I found out.

Summed up, right now I do all my calculations based on the image height first and then check if the screen width's is larger than 1.5 x my image width. Larger means I decrease the height to have two images fit, smaller means I only present one image. Still, I keep getting some undesired results for certain combinations of image sizes / screen resolutions.

If you stumbled upon the same problem and have some code or tips to spare, it would be greatly appreciated.

P.S. As you may figure out, this is about presenting a magazine.

[edit] I forgot to mention that I'm using javascript (vanilla, no plugins/frameworks) for the coding

## Answers

You can use a kd-tree algorithm. A kd-tree hierarchical subdivide the screen into rectangles and uses a data structure similar to a binary tree to store the information. It's uses in many application for example to show the disk space. The Jquery plugin Masonry can do the same. I would also take a look at the Jquery plugin treemap.

To answer my own question, it seems there isn't such an algorithm or at least I wasn't able to find one. The kd-tree suggested is a waaaaaaaaaaaaay too complicated overkill solution to be practical.

In the end, I settled for the one I came up with myself:

- first I check the window height, to see if the largest image fits. If it doesn't, I check if a certain percentage (75%) does. If it's still to large, I downsize the heights
- once I determine a height that fits, I check if two images fit in the total width. If they do, this means I have a double-page mode, otherwise is single page mode

Here is a vanilla javascript implementation

var selCase = 0; //an "ok" var //pageH = array with page heights //pageW = array with page widths //currentWH = window height //currentWW = windowWidth for(i = pageH.length - 1; i >= 0; i--) { if(!selCase) { if(pageH[i] <= currentWH) { //if the page height is lower than the total height if(pageW[i] * 2 <= currentWW) { //if we have room for double pages currentMode = 'L'; currentPW = pageW[i]; currentPH = pageH[i]; selCase = 11; }else { if(currentWW > currentWH) { //if the width is bigger, double-page mode is prefered if((pageW[i] * 1.5) >= (currentWW - 20)) { //there wouldn't be much space left for double-pages currentMode = 'P'; currentPW = pageW[i]; currentPH = pageH[i]; selCase = 12; } // else: the height fits, but not the width so a smaller height is required }else { //standard portrait mode if(pageW[i] <= (currentWW - 20)) { currentMode = 'P'; currentPW = pageW[i]; currentPH = pageH[i]; selCase = 13; } } } }else { //we check to see if maybe we can shrink the page a little to fit in the total height var sPerc; //scale percentage sPerc = currentWH * 100 / pageH[i]; if(sPerc >= perc) { var newW = pageW[i] * sPerc / 100; if(newW * 2 <= (currentWW - 20)) { //if we have room for two also-scaled pages currentMode = 'L'; currentPW = Math.floor(newW); currentPH = currentWH; selCase = 21; }else { if(currentWW > currentWH) { //same as before if((newW * 1.5) >= (currentWW - 20)) { //only one scaled page fits currentMode = 'P'; currentPW = Math.floor(newW); currentPH = currentWH; selCase = 22; } }else { if(newW < (currentWW - 20)) { currentMode = 'P'; currentPW = Math.floor(newW); currentPH = currentWH; selCase = 23; } } } } } } }