# Tangents between two Convex Polygons

Last Updated : 20 Oct, 2023

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

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,

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``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 > a,``                      ``vector > 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 rightmost point of a``    ``int` `ia = 0, ib = 0;``    ``for` `(``int` `i=1; i a[ia].first)``            ``ia = i;` `    ``// ib -> leftmost point of b``    ``for` `(``int` `i=1; i 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 > 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 > 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 {``        ``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 a, List 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 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 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 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``    ``{``        ``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 a, List 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 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 a = ``new` `List();``        ``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 b = ``new` `List();``        ``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.