Finding the best fit rectangle that covers a given point

We are provided with a 2D plane and a point (X, Y). We have to find a rectangle (X_1, Y_1, X_2, Y_2) such that it
encompasses the given point (X, Y). The rectangle chosen must satisfy the given condition \frac{length}{breadth}=\frac{a}{b}. If
multiple rectangles are possible the we must choose the one with the least Euclid distance between the center of the rectangle and the point (X, Y).

Image Source – codeforces
Examples :

Input : 70 10 20 5 5 3
Output :12 0 27 9

Input :100 100 32 63 2 41
Output :30 18 34 100

The logic behind the problem is as follows. First of all we reduce \frac{a}{b} to lowest irreducible form by dividing a and b by gcd(a, b). We think of the problem in two separate dimensions X and Y independently. We find out the min(n/a, m/b) after dividing a and b by their gcd to find the maximum distance that we can cover safely by staying in the range of (0, 0) to (n, m). Since we have to find rectangle with minimum distance of its center from the point (X, Y), therefore we start with the assumption that point (X, Y) is our center. Then we find X_1 and X_2 by subtracting and adding half of length to X. If either X_1 or X_2 goes out of range then we shift the coordinates accordingly to bring it inside the range (0, 0) to (n, m). Similarly we proceed to calculate Y_1 and Y_2.
For the first example according to above logic the answer comes out to be 12, 0, 27, 9.



C++

filter_none

edit
close

play_arrow

link
brightness_4
code

#include <cmath>
#include <iostream>
using namespace std;
  
// Function to claculate
// GCD of a and b
int gcd(int a, int b)
{
    if (a == 0)
        return b;
    else
        return gcd(b % a, a);
}
  
// Function to calculate the
// coordinates of the rectangle
void solve(int n, int m, int x, int y, int a, int b)
{
  
    int k, g;
    int x1, y1, x2, y2;
    g = gcd(a, b);
  
    // Reducing the ratio to
    // lowest irreducible form
    a /= g;
    b /= g;
  
    // Finding the maximum multiple
    // of length that can be chosen
    k = min(n / a, m / b);
  
    // Assuming the point (X, Y) as the
    // centre of the required rectangle
    // Finding the lower X coordinate by
    // subtracting half of total length from X
    x1 = x - (k * a - k * a / 2);
  
    // Finding the upper X coordinate
    // by adding half of total length to X
    x2 = x + k * a / 2;
  
    // Finding lower Y coordinate by
    // subtracting half of breadth from Y
    y1 = y - (k * b - k * b / 2);
  
    // Finding upper Y coordinate
    // by adding half of breadth to Y
    y2 = y + k * b / 2;
  
    // If lower X coordinate
    // goes below 0 then we shift
    // the lower coordinate to 0
    // and the upper coordinate
    // accordingly to bring lower
    // coordinate in range
    // and to keep center as
    // close as possible to X, Y
    if (x1 < 0) {
        x2 -= x1;
        x1 = 0;
    }
  
    // If upper X coordinate goes
    // beyond n, then we shift the
    // upper X coordinate ton
    // and we shift the lower coordinate
    // accordingly to bring the upper
    // coordinate in range
    if (x2 > n) {
        x1 -= x2 - n;
        x2 = n;
    }
  
    // If lower Y coordinate goes
    // below 0 then we shift the
    // lower coordinate to 0
    // and the upper coordinate
    // accordingly to bring lower
    // coordinate in range
    // and to keep center as
    // close as possible to X, Y
    if (y1 < 0) {
        y2 -= y1;
        y1 = 0;
    }
  
    // If upper Y coordinate goes
    // beyond n, then we shift the
    // upper X coordinate
    // to n and we shift the lower
    // coordinate accordingly to
    // bring the upper
    // coordinate in range
    if (y2 > m) {
        y1 -= y2 - m;
        y2 = m;
    }
  
    cout << x1 << " " << y1 << " " << x2
         << " " << y2 << endl;
}
  
// Driver function
int main()
{
    int n = 70, m = 10, x = 20, y = 5, a = 5, b = 3;
    solve(n, m, x, y, a, b);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

class GFG {
  
    // Function to claculate
    // GCD of a and b
    public static int gcd(int a, int b)
    {
        if (a == 0)
            return b;
        else
            return gcd(b % a, a);
    }
  
    // Function to calculate the
    // coordinates of the rectangle
    public static void solve(int n, int m,
                             int x, int y,
                             int a, int b)
    {
  
        int k, g;
        int x1, y1, x2, y2;
        g = gcd(a, b);
  
        // Reducing the ratio to
        // lowest irreducible form
        a /= g;
        b /= g;
  
        // Finding the maximum multiple
        // of length that can be chosen
        k = Math.min(n / a, m / b);
  
        // Assuming the point (X, Y) as the
        // centre of the required rectangle
        // Finding the lower X coordinate by
        // subtracting half of total length
        // from X
        x1 = x - (k * a - k * a / 2);
  
        // Finding the upper X coordinate
        // by adding half of total length
        // to X
        x2 = x + k * a / 2;
  
        // Finding lower Y coordinate by
        // subtracting half of breadth
        // from Y
        y1 = y - (k * b - k * b / 2);
  
        // Finding upper Y coordinate
        // by adding half of breadth
        // to Y
        y2 = y + k * b / 2;
  
        // If lower X coordinate
        // goes below 0 then we shift
        // the lower coordinate to 0
        // and the upper coordinate
        // accordingly to bring lower
        // coordinate in range
        // and to keep center as
        // close as possible to X, Y
        if (x1 < 0) {
            x2 -= x1;
            x1 = 0;
        }
  
        // If upper X coordinate goes
        // beyond n, then we shift the
        // upper X coordinate ton
        // and we shift the lower coordinate
        // accordingly to bring the upper
        // coordinate in range
        if (x2 > n) {
            x1 -= x2 - n;
            x2 = n;
        }
  
        // If lower Y coordinate goes
        // below 0 then we shift the
        // lower coordinate to 0
        // and the upper coordinate
        // accordingly to bring lower
        // coordinate in range
        // and to keep center as
        // close as possible to X, Y
        if (y1 < 0) {
            y2 -= y1;
            y1 = 0;
        }
  
        // If upper Y coordinate goes
        // beyond n, then we shift the
        // upper X coordinate
        // to n and we shift the lower
        // coordinate accordingly to
        // bring the upper
        // coordinate in range
        if (y2 > m) {
            y1 -= y2 - m;
            y2 = m;
        }
  
        System.out.println(x1 + " " + y1 + " " + x2
                           + " " + y2);
    }
  
    // Driver Code
    public static void main(String args[])
    {
        int n = 70, m = 10;
        int x = 20, y = 5;
        int a = 5, b = 3;
        solve(n, m, x, y, a, b);
    }
}
  
// This code is contributed by - vkz6198

chevron_right


Python 3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Function to claculate
# GCD of a and b
def gcd(a, b):
  
    if (a == 0):
        return b
    else:
        return gcd(b % a, a)
  
# Function to calculate the
# coordinates of the rectangle
def solve(n, m, x, y, a, b):
  
    g = int(gcd(a, b))
  
    # Reducing the ratio to
    # lowest irreducible form
    a /= g
    b /= g
  
    # Finding the maximum multiple
    # of length that can be chosen
    k = int(min(n / a, m / b))
  
    # Assuming the point (X, Y) as the
    # centre of the required rectangle
    # Finding the lower X coordinate by
    # subtracting half of total length
    # from X
    x1 = int(x - (k * a - k * a / 2))
  
    # Finding the upper X coordinate
    # by adding half of total length
    # to X
    x2 = int(x + k * a / 2)
  
    # Finding lower Y coordinate by
    # subtracting half of breadth from Y
    y1 = int(y - (k * b - k * b / 2))
  
    # Finding upper Y coordinate
    # by adding half of breadth to Y
    y2 = int(y + k * b / 2)
  
    # If lower X coordinate
    # goes below 0 then we shift
    # the lower coordinate to 0
    # and the upper coordinate
    # accordingly to bring lower
    # coordinate in range
    # and to keep center as
    # close as possible to X, Y
    if (int(x1) < 0): 
        x2 -= x1
        x1 = 0
      
  
    # If upper X coordinate goes
    # beyond n, then we shift the
    # upper X coordinate ton
    # and we shift the lower coordinate
    # accordingly to bring the upper
    # coordinate in range
    if (int(x2) > n):
        x1 -= x2 - n
        x2 = n
      
  
    # If lower Y coordinate goes
    # below 0 then we shift the
    # lower coordinate to 0
    # and the upper coordinate
    # accordingly to bring lower
    # coordinate in range
    # and to keep center as
    # close as possible to X, Y
    if (int(y1) < 0) :
        y2 -= y1
        y1 = 0
      
  
    # If upper Y coordinate goes
    # beyond n, then we shift the
    # upper X coordinate
    # to n and we shift the lower
    # coordinate accordingly to
    # bring the upper
    # coordinate in range
    if (int(y2) > m): 
        y1 -= y2 - m
        y2 = m
      
  
    print(x1 , " " , y1 , " " , x2
        , " " , y2,sep="")
  
# Driver function
n = 70
m = 10
x = 20
y = 5
a = 5
b = 3
solve(n, m, x, y, a, b)
  
# This code is contributed by Smitha

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

using System;
  
class GFG {
  
    // Function to claculate
    // GCD of a and b
    public static int gcd(int a, int b)
    {
        if (a == 0)
            return b;
        else
            return gcd(b % a, a);
    }
  
    // Function to calculate the
    // coordinates of the rectangle
    public static void solve(int n, int m,
                            int x, int y,
                            int a, int b)
    {
  
        int k, g;
        int x1, y1, x2, y2;
        g = gcd(a, b);
  
        // Reducing the ratio to
        // lowest irreducible form
        a /= g;
        b /= g;
  
        // Finding the maximum multiple
        // of length that can be chosen
        k = Math.Min(n / a, m / b);
  
        // Assuming the point (X, Y) as the
        // centre of the required rectangle
        // Finding the lower X coordinate by
        // subtracting half of total length
        // from X
        x1 = x - (k * a - k * a / 2);
  
        // Finding the upper X coordinate
        // by adding half of total length
        // to X
        x2 = x + k * a / 2;
  
        // Finding lower Y coordinate by
        // subtracting half of breadth
        // from Y
        y1 = y - (k * b - k * b / 2);
  
        // Finding upper Y coordinate
        // by adding half of breadth
        // to Y
        y2 = y + k * b / 2;
  
        // If lower X coordinate
        // goes below 0 then we shift
        // the lower coordinate to 0
        // and the upper coordinate
        // accordingly to bring lower
        // coordinate in range
        // and to keep center as
        // close as possible to X, Y
        if (x1 < 0) {
            x2 -= x1;
            x1 = 0;
        }
  
        // If upper X coordinate goes
        // beyond n, then we shift the
        // upper X coordinate ton
        // and we shift the lower coordinate
        // accordingly to bring the upper
        // coordinate in range
        if (x2 > n) {
            x1 -= x2 - n;
            x2 = n;
        }
  
        // If lower Y coordinate goes
        // below 0 then we shift the
        // lower coordinate to 0
        // and the upper coordinate
        // accordingly to bring lower
        // coordinate in range
        // and to keep center as
        // close as possible to X, Y
        if (y1 < 0) {
            y2 -= y1;
            y1 = 0;
        }
  
        // If upper Y coordinate goes
        // beyond n, then we shift the
        // upper X coordinate
        // to n and we shift the lower
        // coordinate accordingly to
        // bring the upper
        // coordinate in range
        if (y2 > m) {
            y1 -= y2 - m;
            y2 = m;
        }
  
        Console.Write(x1 + " " + y1 +
                 " " + x2 + " " + y2);
    }
  
    // Driver Code
    public static void Main()
    {
        int n = 70, m = 10;
        int x = 20, y = 5;
        int a = 5, b = 3;
        solve(n, m, x, y, a, b);
    }
}
  
// This code is contributed by Smitha

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// Function to claculate
// GCD of a and b
  
function gcd($a, $b)
{
    if ($a == 0)
        return $b;
    else
        return gcd($b % $a, $a);
}
  
// Function to calculate the
// coordinates of the rectangle
function solve($n, $m, $x, $y, $a, $b)
{
  
    $k; $g;
    $x1; $y1; $x2; $y2;
    $g = gcd($a, $b);
  
    // Reducing the ratio to
    // lowest irreducible form
    $a /= $g;
    $b /= $g;
  
    // Finding the maximum multiple
    // of length that can be chosen
    $k = min($n / $a, $m / $b);
  
    // Assuming the point (X, Y) 
    // as the centre of the required 
    // rectangle Finding the lower 
    // X coordinate by subtracting
    // half of total length from X
    $x1 = $x - ($k * $a - $k * $a / 2);
  
    // Finding the upper X 
    // coordinate by adding 
    // half of total length to X
    $x2 = $x + $k * $a / 2;
  
    // Finding lower Y coordinate by
    // subtracting half of breadth from Y
    $y1 = $y - ($k * $b - $k * $b / 2);
  
    // Finding upper Y coordinate
    // by adding half of breadth to Y
    $y2 = $y + $k * $b / 2;
  
    // If lower X coordinate
    // goes below 0 then we shift
    // the lower coordinate to 0
    // and the upper coordinate
    // accordingly to bring lower
    // coordinate in range
    // and to keep center as
    // close as possible to X, Y
    if ($x1 < 0) 
    {
        $x2 -= $x1;
        $x1 = 0;
    }
  
    // If upper X coordinate goes
    // beyond n, then we shift the
    // upper X coordinate ton
    // and we shift the lower coordinate
    // accordingly to bring the upper
    // coordinate in range
    if ($x2 > $n
    {
        $x1 -= $x2 - $n;
        $x2 = $n;
    }
  
    // If lower Y coordinate goes
    // below 0 then we shift the
    // lower coordinate to 0
    // and the upper coordinate
    // accordingly to bring lower
    // coordinate in range
    // and to keep center as
    // close as possible to X, Y
    if ($y1 < 0) 
    {
        $y2 -= $y1;
        $y1 = 0;
    }
  
    // If upper Y coordinate goes
    // beyond n, then we shift the
    // upper X coordinate
    // to n and we shift the lower
    // coordinate accordingly to
    // bring the upper
    // coordinate in range
    if ($y2 > $m)
    {
        $y1 -= $y2 - $m;
        $y2 = $m;
    }
  
    echo $x1, " ", $y1, " "
         $x2, " ", $y2, "\n";
}
  
// Driver Code
$n = 70; $m = 10; $x = 20;
$y = 5; $a = 5; $b = 3;
solve($n, $m, $x, $y, $a, $b);
  
// This code is contributed by aj_36
?>

chevron_right


Output :

12 0 27 9


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.