[Math] Formula to best fit a rectangle inside another by scaling

graphing-functionslinear algebrametric-spacestrigonometryvector-spaces

I am very weak in Math. I am a web programmer, and usually my work does not involve too much math – it's more of putting records into databases, pulling out reports, making those fancy web pages etc etc. So, I got a task that is "mathy" for me, but I am hoping it's child's play for some of you Math guys out there, and you will help me out… It might even be an interesting problem for you, its just too complex for me.

So recently I got this task, where I am given an image with an area marked on top of it. This area would be marked as top left pixels (x1,y1) and bottom right pixels (x2,y2)
So for the image I have the following information:

Image Width (iw)
Image Height (ih)
Image Area Top Left (x1,y1)
Image Area Bottom Right (x2,y2)

Now there are a collection of frames, each frame will have Frame Width (fw) and Frame Height (fh). My job is to find optimal way to fit Image Area inside frame without having any blank area inside frame, using image scaling if required.

So I broke it down to following tasks:

  1. Image Area (not fill image) has to fit inside Frame. If Image Area > Frame, I should scale Image down (to a %). If Image Area < Frame I should scale Image Up.

  2. The aspect ratio of the image should not be disturbed when I scale.

  3. I should scale Image based on the longer side of Image Area to make sure that whole Image Area comes inside Frame. However when scaling Image down, sometimes this may cause the other side to have blank space inside Frame because of extreme aspect ratios. In such case, I should only scale down until one side hits Image Height or Image Width. This means that the Image Area is not fully shown inside the Frame, but that is fine because the first priority is to not have blank space inside Frame.

Now that I have written all these rules, I am unable to wrap my head around formalizing this into a mathematical "formula"/"procedure"/"rule-set" that I can then recreate in my software.

For scaling, I found that this formula works well (this is a programming pseudo-code):

imageX = Image.width()
imageY = Image.height();
imageRatio = imageX / imageY;

frameX = Frame.width();
frameY = Frame.height();
frameRatio = frameX / frameY;

if (imageRatio < wellRatio) 
{
    scale = imageX / wellX;
} 
else 
{
    scale = imageY / wellY;
}
resizeX = (imageX / scale);
resizeY = (imageY / scale);

However I do not know how to tie this into the whole picture.

Can anyone help me please? I have been trying unsuccessfully for over a week now 🙁

P.S- I do not know what tags to add for this question, so I would appreciate if anyone reading can update the tags to more correct/relevant ones.

Best Answer

I am not sure how you manage in your program to shrink the image, but the mathematics are as below:

$$scale = \max (\frac{fh}{ih}, \frac{fw}{iw})$$

This gives you the height or width of the image, whichever is "closer" in scale to the frame. Use this as your scale factor will result in the other dimension exceeding the frame, which you said it is OK.

$$iw=iw\cdot scale\\ ih=ih \cdot scale$$ The above two lines gives you the scale to shrink the image.

$$x_2=x_2 +fw\\ y_2=y_2+fh$$

The above two lines change the Bottom Right coordinates.