Open In App
Related Articles

Tangents between two Convex Polygons

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Report issue
Report

Given two convex polygons, we need to find the lower and upper tangents to these polygons. 
As shown in the figure below, T_{RL}         and T_{LR}         show upper and lower tangent respectively.
 

tangent


Examples: 
 

Input : First Polygon  : {(2, 2), (3, 3), (5, 2), (4, 0), (3, 1)} 
Second Polygon : {(-1, 0), (0, 1), (1, 0), (0, -2)}.
Output : Upper Tangent - line joining (0,1) and (3,3)
Lower Tangent - line joining (0,-2) and (4,0)


Overview: 
Let’s have two convex polygons as shown, 
 

tangent2


For finding the upper tangent, we start by taking two points. The rightmost point of a and leftmost point of b. The line joining them is labelled as 1. As this line passes through the polygon b (is not above polygon b) so we take the anti-clockwise next point on b, the line is labelled 2. Now the line is above the polygon b, fine! But the line is crossing the polygon a, so we move to the clockwise next point, labelled as 3 in the picture. This again crossing the polygon a so we move to line 4. This line is crossing b so we move to line 5. Now this line is crossing neither of the points. So this is the upper tangent for the given polygons. 
For finding the lower tangent we need to move inversely through the polygons i.e. if the line is crossing the polygon b we move to clockwise next and to anti-clockwise next if the line is crossing the polygon a.
Algorithm for upper tangent: 
 

L <- line joining the rightmost point of a
and leftmost point of b.
while (L crosses any of the polygons)
{
while(L crosses b)
L <- L' : the point on b moves up.
while(L crosses a)
L <- L' : the point on a moves up.
}


Algorithm for lower tangent: 
 

L <- line joining the rightmost point of a 
and leftmost point of b.
while (L crosses any of the polygons)
{
while (L crosses b)
L <- L' : the point on b moves down.
while (L crosses a)
L <- L' : the point on a moves down.
}


 Example :

CPP

// C++ program to find upper tangent of two polygons.
#include<bits/stdc++.h>
using namespace std;
 
// stores the center of polygon (It is made
// global because it is used in compare function)
pair<int,int> mid;
 
// determines the quadrant of a point
// (used in compare())
int quad(pair<int,int> p)
{
    if (p.first >= 0 && p.second >= 0)
        return 1;
    if (p.first <= 0 && p.second >= 0)
        return 2;
    if (p.first <= 0 && p.second <= 0)
        return 3;
    return 4;
}
 
// Checks whether the line is crossing the polygon
int orientation(pair<int,int> a, pair<int,int> b,
                                 pair<int,int> c)
{
    int res = (b.second-a.second)*(c.first-b.first) -
              (c.second-b.second)*(b.first-a.first);
 
    if (res == 0)
        return 0;
    if (res > 0)
        return 1;
    return -1;
}
 
// compare function for sorting
bool compare(pair<int,int> p1, pair<int,int> q1)
{
    pair<int,int> p = make_pair(p1.first - mid.first,
                                p1.second - mid.second);
    pair<int,int> q = make_pair(q1.first - mid.first,
                                q1.second - mid.second);
 
    int one = quad(p);
    int two = quad(q);
 
    if (one != two)
        return (one < two);
    return (p.second*q.first < q.second*p.first);
}
 
// Finds upper tangent of two polygons 'a' and 'b'
// represented as two vectors.
void findUpperTangent(vector<pair<int,int> > a,
                      vector<pair<int,int> > b)
{
    // n1 -> number of points in polygon a
    // n2 -> number of points in polygon b
    int n1 = a.size(), n2 = b.size();
 
    // To find a point inside the convex polygon(centroid),
    // we sum up all the coordinates and then divide  by
    // n(number of points). But this would be a floating-point
    // value. So to get rid of this we multiply points
    // initially with n1 and then find the centre and
    // then divided it by n1 again.
    // Similarly we do divide and multiply for n2 (i.e.,
    // elements of b)
 
    // maxa and minb are used to check if polygon a
    // is left of b.
    int maxa = INT_MIN;
    for (int i=0; i<n1; i++)
    {
        maxa = max(maxa, a[i].first);
        mid.first  += a[i].first;
        mid.second += a[i].second;
        a[i].first *= n1;
        a[i].second *= n1;
    }
 
    // sorting the points in counter clockwise order
    // for polygon a
    sort(a.begin(), a.end(), compare);
 
    for (int i=0; i<n1; i++)
    {
        a[i].first /= n1;
        a[i].second /= n1;
    }
 
    mid = {0, 0};
 
    int minb = INT_MAX;
    for (int i=0; i<n2; i++)
    {
        mid.first += b[i].first;
        mid.second += b[i].second;
        minb = min(minb, b[i].first);
        b[i].first *= n2;
        b[i].second *= n2;
    }
 
    // sorting the points in counter clockwise
    // order for polygon b
    sort(b.begin(), b.end(), compare);
 
    for (int i=0; i<n2; i++)
    {
        b[i].first/=n2;
        b[i].second/=n2;
    }
 
    // If a is to the right of b, swap a and b
    // This makes sure a is left of b.
    if (minb < maxa)
    {
        a.swap(b);
        n1 = a.size();
        n2 = b.size();
    }
 
    // ia -> rightmost point of a
    int ia = 0, ib = 0;
    for (int i=1; i<n1; i++)
        if (a[i].first > a[ia].first)
            ia = i;
 
    // ib -> leftmost point of b
    for (int i=1; i<n2; i++)
        if (b[i].first < b[ib].first)
            ib=i;
 
    // finding the upper tangent
    int inda = ia, indb = ib;
    bool done = 0;
    while (!done)
    {
        done = 1;
        while (orientation(b[indb], a[inda], a[(inda+1)%n1]) > 0)
            inda = (inda + 1) % n1;
 
        while (orientation(a[inda], b[indb], b[(n2+indb-1)%n2]) < 0)
        {
            indb = (n2+indb-1)%n2;
            done = 0;
        }
    }
 
    cout << "upper tangent (" << a[inda].first << ","
        << a[inda].second << ") (" << b[indb].first
        << "," << b[indb].second << ")\n";
}
 
// Driver code
int main()
{
    vector<pair<int,int> > a;
    a.push_back({2, 2});
    a.push_back({3, 1});
    a.push_back({3, 3});
    a.push_back({5, 2});
    a.push_back({4, 0});
 
    vector<pair<int,int> > b;
    b.push_back({0, 1});
    b.push_back({1, 0});
    b.push_back({0, -2});
    b.push_back({-1, 0});
 
    findUpperTangent(a, b);
 
    return 0;
}

                    

Java

// Java program to find upper tangent of two polygons.
import java.util.*;
 
public class UpperTangentFinder {
    // Class representing a 2D point
    static class Point {
        int x, y;
 
        Point() {
            x = 0;
            y = 0;
        }
 
        Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }
 
    // Stores the center of polygon (It is made
    // global because it is used in compare function)
    static Point mid = new Point();
 
    // Determines the quadrant of a point
    // (used in compare())
    static int quad(Point p) {
        if (p.x >= 0 && p.y >= 0)
            return 1;
        if (p.x <= 0 && p.y >= 0)
            return 2;
        if (p.x <= 0 && p.y <= 0)
            return 3;
        return 4;
    }
 
    // Checks whether the line is crossing the polygon
    static int orientation(Point a, Point b, Point c) {
        int res = (b.y - a.y) * (c.x - b.x) - (c.y - b.y) * (b.x - a.x);
 
        if (res == 0)
            return 0;
        if (res > 0)
            return 1;
        return -1;
    }
 
    // Compare function for sorting
    static class PointComparator implements Comparator<Point> {
        public int compare(Point p1, Point p2) {
            Point p = new Point(p1.x - mid.x, p1.y - mid.y);
            Point q = new Point(p2.x - mid.x, p2.y - mid.y);
 
            int one = quad(p);
            int two = quad(q);
 
            if (one != two)
                return one - two;
            return p.y * q.x - q.y * p.x;
        }
    }
 
    // Finds upper tangent of two polygons 'a' and 'b'
    // represented as two lists of points.
    static void findUpperTangent(List<Point> a, List<Point> b) {
        // n1 -> number of points in polygon a
        // n2 -> number of points in polygon b
        int n1 = a.size(), n2 = b.size();
 
        // To find a point inside the convex polygon (centroid),
        // we sum up all the coordinates and then divide by
        // n (number of points). But this would be a floating-point
        // value. So to get rid of this, we multiply points
        // initially with n1 and then find the center and
        // then divide it by n1 again.
        // Similarly, we do divide and multiply for n2 (i.e.,
        // elements of b)
 
        // maxa and minb are used to check if polygon a
        // is left of b.
        int maxa = Integer.MIN_VALUE;
        for (int i = 0; i < n1; i++) {
            maxa = Math.max(maxa, a.get(i).x);
            mid.x += a.get(i).x;
            mid.y += a.get(i).y;
            a.get(i).x *= n1;
            a.get(i).y *= n1;
        }
 
        // Sorting the points in counter-clockwise order
        // for polygon a
        a.sort(new PointComparator());
 
        for (int i = 0; i < n1; i++) {
            a.get(i).x /= n1;
            a.get(i).y /= n1;
        }
 
        mid.x = 0;
        mid.y = 0;
 
        int minb = Integer.MAX_VALUE;
        for (int i = 0; i < n2; i++) {
            mid.x += b.get(i).x;
            mid.y += b.get(i).y;
            minb = Math.min(minb, b.get(i).x);
            b.get(i).x *= n2;
            b.get(i).y *= n2;
        }
 
        // Sorting the points in counter-clockwise
        // order for polygon b
        b.sort(new PointComparator());
 
        for (int i = 0; i < n2; i++) {
            b.get(i).x /= n2;
            b.get(i).y /= n2;
        }
 
        // If a is to the right of b, swap a and b
        // This makes sure a is left of b.
        if (minb < maxa) {
            List<Point> temp = a;
            a = b;
            b = temp;
            n1 = a.size();
            n2 = b.size();
        }
 
        // ia -> rightmost point of a
        int ia = 0, ib = 0;
        for (int i = 1; i < n1; i++) {
            if (a.get(i).x > a.get(ia).x)
                ia = i;
        }
 
        // ib -> leftmost point of b
        for (int i = 1; i < n2; i++) {
            if (b.get(i).x < b.get(ib).x)
                ib = i;
        }
 
        // Finding the upper tangent
        int inda = ia, indb = ib;
        boolean done = false;
        while (!done) {
            done = true;
            while (orientation(b.get(indb), a.get(inda), a.get((inda + 1) % n1)) > 0)
                inda = (inda + 1) % n1;
 
            while (orientation(a.get(inda), b.get(indb), b.get((n2 + indb - 1) % n2)) < 0) {
                indb = (n2 + indb - 1) % n2;
                done = false;
            }
        }
 
        System.out.println("upper tangent (" + a.get(inda).x + "," + a.get(inda).y + ") (" + b.get(indb).x + "," + b.get(indb).y + ")");
    }
 
    // Driver code
    public static void main(String[] args) {
        List<Point> a = new ArrayList<>();
        a.add(new Point(2, 2));
        a.add(new Point(3, 1));
        a.add(new Point(3, 3));
        a.add(new Point(5, 2));
        a.add(new Point(4, 0));
 
        List<Point> b = new ArrayList<>();
        b.add(new Point(0, 1));
        b.add(new Point(1, 0));
        b.add(new Point(0, -2));
        b.add(new Point(-1, 0));
 
        findUpperTangent(a, b);
    }
}

                    

Python3

# program to find upper tangent of two polygons.
from functools import cmp_to_key
 
# stores the centre of polygon (It is made
# global because it is used in compare function)
mid = [0, 0]
 
# determines the quadrant of a point
# (used in compare())
def quad(p):
    if p[0] >= 0 and p[1] >= 0:
        return 1
    if p[0] <= 0 and p[1] >= 0:
        return 2
    if p[0] <= 0 and p[1] <= 0:
        return 3
    return 4
 
   
# Checks whether the line is crossing the polygon
def orientation(a, b, c):
    res = (b[1]-a[1]) * (c[0]-b[0]) - (c[1]-b[1]) * (b[0]-a[0])
    if res == 0:
        return 0
    if res > 0:
        return 1
    return -1
 
   
# compare function for sorting
def compare(p1, q1):
    p = [p1[0]-mid[0], p1[1]-mid[1]]
    q = [q1[0]-mid[0], q1[1]-mid[1]]
    one = quad(p)
    two = quad(q)
 
    if one != two:
        if one < two:
            return -1
        return 1
    if p[1]*q[0] < q[1]*p[0]:
        return -1
    return 1
 
   
#  Finds upper tangent of two polygons 'a' and 'b'
# represented as two vectors.
def findUpperTangent(a, b):
    global mid
    # n1 -> number of points in polygon a
    # n2 -> number of points in polygon b
    n1, n2 = len(a), len(b)
 
    # To find a point inside the convex polygon(centroid),
    # we sum up all the coordinates and then divide  by
    # n(number of points). But this would be a floating-point
    # value. So to get rid of this we multiply points
    # initially with n1 and then find the centre and
    # then divided it by n1 again.
    # Similarly we do divide and multiply for n2 (i.e.,
    # elements of b)
 
    # maxa and minb are used to check if polygon a
    # is left of b.
    maxa = float('-inf')
    for i in range(n1):
        maxa = max(maxa, a[i][0])
        mid[0] += a[i][0]
        mid[1] += a[i][1]
        a[i][0] *= n1
        a[i][1] *= n1
 
    # sorting the points in counter clockwise order
    # for polygon a
    a = sorted(a, key=cmp_to_key(compare))
    for i in range(n1):
        a[i][0] /= n1
        a[i][1] /= n1
 
    mid = [0, 0]
    minb = float('inf')
    for i in range(n2):
        minb = min(minb, b[i][0])
        mid[0] += b[i][0]
        mid[1] += b[i][1]
        b[i][0] *= n2
        b[i][1] *= n2
 
    # sorting the points in counter clockwise
    # order for polygon b
    sorted(b, key=cmp_to_key(compare))
    for i in range(n2):
        b[i][0] /= n2
        b[i][1] /= n2
 
    # If a is to the right of b, swap a and b
    # This makes sure a is left of b.
    if minb < maxa:
        a, b = b, a
        n1, n2 = n2, n1
 
    ia, ib = 0, 0
    # ia -> leftmost point of a
    for i in range(1, n1):
        if a[i][0] > a[ia][0]:
            ia = i
 
    # ib -> leftmost point of b
    for i in range(1, n2):
        if b[i][0] < b[ib][0]:
            ib = i
 
    # finding the upper tangent
    inda, indb = ia, ib
    done = 0
    while not done:
        done = 1
        while orientation(b[indb], a[inda], a[(inda+1) % n1]) >= 0:
            inda = (inda + 1) % n1
 
        while orientation(a[inda], b[indb], b[(n2+indb-1) % n2]) <= 0:
            indb = (n2 + indb - 1) % n2
            done = 0
 
    print('upper tangent (%d, %d) (%d, %d)' %
          (a[inda][0], a[inda][1], b[indb][0], b[indb][1]))
 
 
# Driver Code
if __name__ == '__main__':
    a = []
    a.append([2, 2])
    a.append([3, 1])
    a.append([3, 3])
    a.append([5, 2])
    a.append([4, 0])
 
    b = []
    b.append([0, 1])
    b.append([1, 0])
    b.append([0, -2])
    b.append([-1, 0])
 
    findUpperTangent(a, b)

                    

C#

using System;
using System.Collections.Generic;
 
public class UpperTangentFinder
{
    // Class representing a 2D point
    public class Point
    {
        public int x, y;
 
        public Point()
        {
            x = 0;
            y = 0;
        }
 
        public Point(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
    }
 
    // Stores the center of polygon (It is made
    // global because it is used in compare function)
    static Point mid = new Point();
 
    // Determines the quadrant of a point
    // (used in compare())
    static int Quad(Point p)
    {
        if (p.x >= 0 && p.y >= 0)
            return 1;
        if (p.x <= 0 && p.y >= 0)
            return 2;
        if (p.x <= 0 && p.y <= 0)
            return 3;
        return 4;
    }
 
    // Checks whether the line is crossing the polygon
    static int Orientation(Point a, Point b, Point c)
    {
        int res = (b.y - a.y) * (c.x - b.x) - (c.y - b.y) * (b.x - a.x);
 
        if (res == 0)
            return 0;
        if (res > 0)
            return 1;
        return -1;
    }
 
    // Compare function for sorting
    public class PointComparer : IComparer<Point>
    {
        public int Compare(Point p1, Point p2)
        {
            Point p = new Point(p1.x - mid.x, p1.y - mid.y);
            Point q = new Point(p2.x - mid.x, p2.y - mid.y);
 
            int one = Quad(p);
            int two = Quad(q);
 
            if (one != two)
                return one - two;
            return p.y * q.x - q.y * p.x;
        }
    }
 
    // Finds upper tangent of two polygons 'a' and 'b'
    // represented as two lists of points.
    static void FindUpperTangent(List<Point> a, List<Point> b)
    {
        // n1 -> number of points in polygon a
        // n2 -> number of points in polygon b
        int n1 = a.Count, n2 = b.Count;
 
        // To find a point inside the convex polygon (centroid),
        // we sum up all the coordinates and then divide by
        // n (number of points). But this would be a floating-point
        // value. So to get rid of this, we multiply points
        // initially with n1 and then find the center and
        // then divide it by n1 again.
        // Similarly, we do divide and multiply for n2 (i.e.,
        // elements of b)
 
        // maxa and minb are used to check if polygon a
        // is left of b.
        int maxa = int.MinValue;
        for (int i = 0; i < n1; i++)
        {
            maxa = Math.Max(maxa, a[i].x);
            mid.x += a[i].x;
            mid.y += a[i].y;
            a[i].x *= n1;
            a[i].y *= n1;
        }
 
        // Sorting the points in counter-clockwise order
        // for polygon a
        a.Sort(new PointComparer());
 
        for (int i = 0; i < n1; i++)
        {
            a[i].x /= n1;
            a[i].y /= n1;
        }
 
        mid.x = 0;
        mid.y = 0;
 
        int minb = int.MaxValue;
        for (int i = 0; i < n2; i++)
        {
            mid.x += b[i].x;
            mid.y += b[i].y;
            minb = Math.Min(minb, b[i].x);
            b[i].x *= n2;
            b[i].y *= n2;
        }
 
        // Sorting the points in counter-clockwise
        // order for polygon b
        b.Sort(new PointComparer());
 
        for (int i = 0; i < n2; i++)
        {
            b[i].x /= n2;
            b[i].y /= n2;
        }
 
        // If a is to the right of b, swap a and b
        // This makes sure a is left of b.
        if (minb < maxa)
        {
            List<Point> temp = a;
            a = b;
            b = temp;
            n1 = a.Count;
            n2 = b.Count;
        }
 
        // ia -> rightmost point of a
        int ia = 0, ib = 0;
        for (int i = 1; i < n1; i++)
        {
            if (a[i].x > a[ia].x)
                ia = i;
        }
 
        // ib -> leftmost point of b
        for (int i = 1; i < n2; i++)
        {
            if (b[i].x < b[ib].x)
                ib = i;
        }
 
        // Finding the upper tangent
        int inda = ia, indb = ib;
        bool done = false;
        while (!done)
        {
            done = true;
            while (Orientation(b[indb], a[inda], a[(inda + 1) % n1]) > 0)
                inda = (inda + 1) % n1;
 
            while (Orientation(a[inda], b[indb], b[(n2 + indb - 1) % n2]) < 0)
            {
                indb = (n2 + indb - 1) % n2;
                done = false;
            }
        }
 
        Console.WriteLine("upper tangent (" + a[inda].x + "," + a[inda].y + ") (" + b[indb].x + "," + b[indb].y + ")");
    }
 
    // Driver code
    public static void Main(string[] args)
    {
        List<Point> a = new List<Point>();
        a.Add(new Point(2, 2));
        a.Add(new Point(3, 1));
        a.Add(new Point(3, 3));
        a.Add(new Point(5, 2));
        a.Add(new Point(4, 0));
 
        List<Point> b = new List<Point>();
        b.Add(new Point(0, 1));
        b.Add(new Point(1, 0));
        b.Add(new Point(0, -2));
        b.Add(new Point(-1, 0));
 
        FindUpperTangent(a, b);
    }
}

                    

Javascript

// Javascript program to find upper tangent of two polygons.
 
// Stores the center of the polygon (made global for use in compare function)
let mid = [0, 0];
 
// Determines the quadrant of a point (used in compare())
function quad(p) {
    if (p[0] >= 0 && p[1] >= 0) {
        return 1;
    }
    if (p[0] <= 0 && p[1] >= 0) {
        return 2;
    }
    if (p[0] <= 0 && p[1] <= 0) {
        return 3;
    }
    return 4;
}
 
// Checks whether the line is crossing the polygon
function orientation(a, b, c) {
    const res = (b[1] - a[1]) * (c[0] - b[0]) - (c[1] - b[1]) * (b[0] - a[0]);
    if (res === 0) {
        return 0;
    }
    if (res > 0) {
        return 1;
    }
    return -1;
}
 
// Compare function for sorting
function compare(p1, q1) {
    const p = [p1[0] - mid[0], p1[1] - mid[1]];
    const q = [q1[0] - mid[0], q1[1] - mid[1]];
    const one = quad(p);
    const two = quad(q);
 
    if (one !== two) {
        if (one < two) {
            return -1;
        }
        return 1;
    }
    if (p[1] * q[0] < q[1] * p[0]) {
        return -1;
    }
    return 1;
}
 
// Finds upper tangent of two polygons 'a' and 'b' represented as two arrays of points.
function findUpperTangent(a, b) {
    // n1 -> number of points in polygon a
    // n2 -> number of points in polygon b
    let n1 = a.length;
    let n2 = b.length;
 
    // To find a point inside the convex polygon (centroid),
    // we sum up all the coordinates and then divide by
    // n (number of points). But this would be a floating-point
    // value. So to get rid of this we multiply points
    // initially with n1 and then find the center and
    // then divide it by n1 again.
    // Similarly, we do divide and multiply for n2 (i.e.,
    // elements of b)
 
    // maxa and minb are used to check if polygon a
    // is left of b.
    let maxa = Number.NEGATIVE_INFINITY;
    for (let i = 0; i < n1; i++) {
        maxa = Math.max(maxa, a[i][0]);
        mid[0] += a[i][0];
        mid[1] += a[i][1];
        a[i][0] *= n1;
        a[i][1] *= n1;
    }
 
    // Sorting the points in counterclockwise order for polygon a
    a.sort((p1, p2) => compare(p1, p2));
    for (let i = 0; i < n1; i++) {
        a[i][0] /= n1;
        a[i][1] /= n1;
    }
 
    mid = [0, 0];
    let minb = Number.POSITIVE_INFINITY;
    for (let i = 0; i < n2; i++) {
        minb = Math.min(minb, b[i][0]);
        mid[0] += b[i][0];
        mid[1] += b[i][1];
        b[i][0] *= n2;
        b[i][1] *= n2;
    }
 
    // Sorting the points in counterclockwise order for polygon b
    b.sort((p1, p2) => compare(p1, p2));
    for (let i = 0; i < n2; i++) {
        b[i][0] /= n2;
        b[i][1] /= n2;
    }
 
    // If a is to the right of b, swap a and b
    // This makes sure a is left of b.
    if (minb < maxa) {
        [a, b] = [b, a];
        [n1, n2] = [n2, n1];
    }
 
    let ia = 0; // leftmost point of a
    for (let i = 1; i < n1; i++) {
        if (a[i][0] > a[ia][0]) {
            ia = i;
        }
    }
 
    let ib = 0; // leftmost point of b
    for (let i = 1; i < n2; i++) {
        if (b[i][0] < b[ib][0]) {
            ib = i;
        }
    }
 
    // Finding the upper tangent
    let inda = ia;
    let indb = ib;
    let done = 0;
    while (!done) {
        done = 1;
        while (orientation(b[indb], a[inda], a[(inda + 1) % n1]) >= 0) {
            inda = (inda + 1) % n1;
        }
 
        while (orientation(a[inda], b[indb], b[(n2 + indb - 1) % n2]) <= 0) {
            indb = (n2 + indb - 1) % n2;
            done = 0;
        }
    }
 
    console.log(`Upper tangent (${a[inda][0]}, ${a[inda][1]}) (${b[indb][0]}, ${b[indb][1]})`);
}
 
// Driver Code
const a = [
    [2, 2],
    [3, 1],
    [3, 3],
    [5, 2],
    [4, 0]
];
 
const b = [
    [0, 1],
    [1, 0],
    [0, -2],
    [-1, 0]
];
 
findUpperTangent(a, b);

                    

Output: 
 

Upper tangent (0,1) (3,3)

Time Complexity: O(n1 log (n1) + n2 log(n2)) 
Auxiliary Space: O(1)


Note that the above code only finds upper tangent. We can similarly find lower tangent.
This article is contributed by Aarti_Rathi and Amritya Vagmi and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org.

 



Last Updated : 20 Oct, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads