Fred Fickleberry III
Fred Fickleberry III

Reputation: 2529

Calculate size of rectangle when canvas changes aspect ratio

I have a desktop application that shows a virtual representation of the user's screen. The ratio of the canvas inside my application does not match the ratio of the user's screen.

enter image description here

Inside my application the user can add a rectangle shaped section on the screen. When the rectangle is added, the default size on the actual desktop is 450x300. So I need to resize the rectangle in the virtual desktop to reflect that.

So I can't simply do this:

double virtualRectWidth = VirtualResolutionX / (RealResolutionX / 450);
double virtualRectHeight = virtualRectWidth / (RealResolutionX / RealResolutionY);

The aspect ratio would not match.

How do I adjust the size of the virtual rectangle?

Upvotes: 1

Views: 1158

Answers (1)

user2480047
user2480047

Reputation:

If you wan to account for all the possible options (real height/width bigger/smaller than virtual height/width) and to make sure that the best configuration is delivered (the rescaling occurs such that the available space is maximised), it is not so straightforward. The code below accounts for all the eventualities:

double safeRatio = 0.95; //Avoiding identical height/width
double heightWidthRatio = virtualRectHeight / virtualRectWidth; //450 / 300
double diffWidth = safeRatio * realRectWidth - virtualRectWidth;
double diffHeight = safeRatio * realRectHeight - virtualRectHeight;
double virtualRectWidth_final = virtualRectWidth;
double virtualRectHeight_final = virtualRectHeight;

if (diffWidth <= 0 && diffHeight <= 0) //virtualRectWidth >= safeRatio*realRectWidth and virtualRectHeight >= safeRatio*realRectHeight
{
    int counterDec = 10;
    if(Math.Abs(diffWidth) > Math.Abs(diffHeight))
    {
         virtualRectWidth_final = safeRatio * realRectWidth + counterDec;
         do
         {
              virtualRectWidth_final = safeRatio * realRectWidth - counterDec;
              virtualRectHeight_final = virtualRectWidth_final * heightWidthRatio;
         } while(virtualRectHeight_final > safeRatio * realRectHeight);
    }
    else
    {
         virtualRectHeight_final = safeRatio * realRectHeight + counterDec;
         do
         {
              virtualRectHeight_final = safeRatio * realRectHeight - counterDec;
              virtualRectWidth_final = virtualRectHeight_final / heightWidthRatio;
         } while(virtualRectWidth_final > safeRatio * realRectWidth);
    }
}
else if (diffWidth <= 0) //virtualRectWidth >= safeRatio*realRectWidth
{
    virtualRectWidth_final = safeRatio * realRectWidth;
    virtualRectHeight_final = virtualRectWidth_final * heightWidthRatio;
    if (virtualRectHeight_final >= safeRatio * realRectHeight) 
    {
        virtualRectHeight_final = safeRatio * realRectHeight;
        virtualRectWidth_final = virtualRectHeight_final / heightWidthRatio;
    }
}
else if (diffHeight <= 0) //virtualRectHeight >= safeRatio*realRectHeight
{
    virtualRectHeight_final = safeRatio * realRectHeight;
    virtualRectWidth_final = virtualRectHeight_final / heightWidthRatio;
    if (virtualRectWidth_final >= safeRatio * realRectWidth)
    {
        virtualRectWidth_final = safeRatio * realRectWidth;
        virtualRectHeight_final = virtualRectWidth_final * heightWidthRatio;
    }
}
else //virtualRectWidth < safeRatio*realRectWidth && virtualRectHeight < safeRatio*realRectHeight
{
    if (diffWidth < diffHeight)
    {
        virtualRectHeight_final = virtualRectWidth_final * heightWidthRatio;
    }
    else
    {
        virtualRectWidth_final = virtualRectHeight_final / heightWidthRatio;
    }
}

The final values are given by virtualRectWidth_final and virtualRectHeight_final. With a bit of work, you might reduce the size of the code but what matters here is the result and well... I have done enough just to answer your question.

Upvotes: 1

Related Questions