Open In App

Maximum distance between two points in coordinate plane using Rotating Caliper’s Method

Prerequisites: Graham Scan’s Convex Hull, Orientation.
Given a set of N points in a coordinates plane, the task is to find the maximum distance between any two points in the given set of planes.

Examples: 

Input: n = 4, Points: (0, 3), (3, 0), (0, 0), (1, 1) 
Output: Maximum Distance = 4.24264     
Explanation: 
Points having maximum distance between them are (0, 3) and (3, 0) 

Input: n = 5, Points: (4, 0), (0, 2), (-1, -7), (1, 10), (2, -3) 
Output: Maximum Distance = 17.11724 
Explanation: 
Points having maximum distance between them are (-1, 7) and (1, 10) 

Naive Approach: The naive idea is to try every possible pair of points from the given set and calculate the distances between each of them and print the maximum distance among all the pairs.

Below is the implementation of the above approach:

#include <bits/stdc++.h>
using namespace std;
 
// Function calculates distance
// between two points
long dist(pair<long, long> p1,
          pair<long, long> p2)
{
    long x0 = p1.first - p2.first;
    long y0 = p1.second - p2.second;
    return x0 * x0 + y0 * y0;
}
 
// Function to find the maximum
// distance between any two points
double maxDist(pair<long, long> p[], int n)
{
    double Max = 0;
 
    // Iterate over all possible pairs
    for(int i = 0; i < n; i++)
    {
        for(int j = i + 1; j < n; j++)
        {
             
            // Update max
            Max = max(Max, (double)dist(p[i],
                                        p[j]));
        }
    }
 
    // Return actual distance
    return sqrt(Max);
}
 
// Driver code  
int main()
{
     
    // Number of points
    int n = 5;
 
    pair<long, long> p[n];
 
    // Given points
    p[0].first = 4, p[0].second = 0;
    p[1].first = 0, p[1].second = 2;
    p[2].first = -1, p[2].second = -7;
    p[3].first = 1, p[3].second = 10;
    p[4].first = 2, p[4].second = -3;
 
    // Function call
    cout << fixed << setprecision(14)
         << maxDist(p, n) <<endl;
 
    return 0;
}
 
// This code is contributed by divyeshrabadiya07

                    
import java.awt.*;
import java.util.ArrayList;
 
public class Main {
 
    // Function calculates distance
    // between two points
    static long dist(Point p1, Point p2)
    {
        long x0 = p1.x - p2.x;
        long y0 = p1.y - p2.y;
        return x0 * x0 + y0 * y0;
    }
 
    // Function to find the maximum
    // distance between any two points
    static double maxDist(Point p[])
    {
        int n = p.length;
        double max = 0;
 
        // Iterate over all possible pairs
        for (int i = 0; i < n; i++) {
 
            for (int j = i + 1; j < n; j++) {
 
                // Update max
                max = Math.max(max,
                               dist(p[i],
                                    p[j]));
            }
        }
 
        // Return actual distance
        return Math.sqrt(max);
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        // Number of points
        int n = 5;
 
        Point p[] = new Point[n];
 
        // Given points
        p[0] = new Point(4, 0);
        p[1] = new Point(0, 2);
        p[2] = new Point(-1, -7);
        p[3] = new Point(1, 10);
        p[4] = new Point(2, -3);
 
        // Function Call
        System.out.println(maxDist(p));
    }
}

                    
from math import sqrt
 
# Function calculates distance
# between two points
def dist(p1, p2):
     
    x0 = p1[0] - p2[0]
    y0 = p1[1] - p2[1]
    return x0 * x0 + y0 * y0
 
# Function to find the maximum
# distance between any two points
def maxDist(p):
 
    n = len(p)
    maxm = 0
 
    # Iterate over all possible pairs
    for i in range(n):
        for j in range(i + 1, n):
             
            # Update maxm
            maxm = max(maxm, dist(p[i], p[j]))
 
    # Return actual distance
    return sqrt(maxm)
     
# Driver Code
if __name__ == '__main__':
     
    # Number of points
    n = 5
 
    p = []
     
    # Given points
    p.append([4, 0])
    p.append([0, 2])
    p.append([-1, -7])
    p.append([1, 10])
    p.append([2, -3])
 
    # Function Call
    print(maxDist(p))
 
# This code is contributed by mohit kumar 29

                    
using System;
class GFG {
     
    // Function calculates distance
    // between two points
    static long dist(Tuple<int, int> p1, Tuple<int, int> p2)
    {
        long x0 = p1.Item1 - p2.Item1;
        long y0 = p1.Item2 - p2.Item2;
        return x0 * x0 + y0 * y0;
    }
  
    // Function to find the maximum
    // distance between any two points
    static double maxDist(Tuple<int, int>[] p)
    {
        int n = p.Length;
        double max = 0;
  
        // Iterate over all possible pairs
        for (int i = 0; i < n; i++) {
  
            for (int j = i + 1; j < n; j++) {
  
                // Update max
                max = Math.Max(max, dist(p[i],p[j]));
            }
        }
  
        // Return actual distance
        return Math.Sqrt(max);
    }
 
  // Driver code
  static void Main() {
      
        // Given points
        Tuple<int, int>[] p =
        {
            Tuple.Create(4, 0),
            Tuple.Create(0, 2),
            Tuple.Create(-1, -7),
            Tuple.Create(1, 10),
            Tuple.Create(2, -3),
        };
       
        // Function Call
        Console.WriteLine(maxDist(p));
  }
}
 
// This code is contributed by divyesh072019

                    
<script>
      // Function calculates distance
      // between two points
      function dist(p1, p2) {
        var x0 = p1[0] - p2[0];
        var y0 = p1[1] - p2[1];
        return x0 * x0 + y0 * y0;
      }
      // Function to find the maximum
      // distance between any two points
      function maxDist(p) {
        var n = p.length;
        var maxm = 0;
 
        // Iterate over all possible pairs
        for (let i = 0; i < n; i++) {
          for (let j = i + 1; j < n; j++) {
            // Update maxm
            maxm = Math.max(maxm, dist(p[i], p[j]));
          }
        }
        // Return actual distance
        return Math.sqrt(maxm);
      }
      // Driver Code
      // Number of points
      var n = 5;
 
      var p = [];
 
      // Given points
      p.push([4, 0]);
      p.push([0, 2]);
      p.push([-1, -7]);
      p.push([1, 10]);
      p.push([2, -3]);
 
      // Function Call
      document.write(maxDist(p));
    </script>

                    

Output
17.11724276862369


Time Complexity: O(N2), where N is the total number of points. 
Auxiliary Space: O(1)

Efficient Approach: The above naive approach can be optimized using Rotating Caliper’s Method.

Rotating Calipers is a method for solving a number of problems from the field of computational geometry. It resembles the idea of rotating an adjustable caliper around the outside of a polygon’s convex hull. Originally, this method was invented to compute the diameter of convex polygons. It can also be used to compute the minimum and maximum distance between two convex polygons, the intersection of convex polygons, the maximum distance between two points in a polygon, and many things more. 

To implement the above method we will use the concept of the Convex Hull. Before we begin a further discussion about the optimal approach, we need to know about the following:

Relative Area of Triangle = abs((x2-x1)*(y3-y2)-(x3-x2)*(y2-y1)) 

Below are the steps:

  1. Two points having maximum distance must lie on the boundary of the convex polygon formed from the given set. Therefore, use Graham Scan’s convex hull method to arrange points in counter-clockwise order.
  2. We have N points, Initially start from point P1 and include those points from set of given points such that area of region always increases by including any points from the set.
  3. Starting from point P1, Choose K = 2 and increment K while area(PN, P1, PK) is increasing and stop before it starts decreasing. Now the current point PK might be the antipodal point for P1. Similarly, find antipodal point for p2 by finding area(P1, P2, PK) and incrementing K form where we previously stopped and so on.
  4. Keep updating the maximum distance for each antipodal points occurs in the above steps as the distance between initial point and point by including area was maximum.

Below is the implementation of the above approach:

#include <bits/stdc++.h>
using namespace std;
 
// A small constant to handle precision errors
const double EPS = 1e-9;
 
// A struct to represent a 2D point
struct Point {
    double x, y;
    Point(double x = 0, double y = 0) : x(x), y(y) {}
};
 
// A function to calculate the squared distance between two points
double dist(Point p, Point q) {
    return (p.x - q.x) * (p.x - q.x) + (p.y - q.y) * (p.y - q.y);
}
 
// A function to calculate the absolute area of a triangle
double absArea(Point p, Point q, Point r) {
    return abs((p.x * q.y + q.x * r.y + r.x * p.y) -
               (p.y * q.x + q.y * r.x + r.y * p.x));
}
 
// A function to calculate the convex hull of a set of points
vector<Point> convexHull(vector<Point>& points) {
   
    int n = points.size();
   
      // Sort the points by x-coordinate (in case of a tie, by y-coordinate)
    sort(points.begin(), points.end(), [](Point a, Point b) {
        if (a.x != b.x) return a.x < b.x;
        return a.y < b.y;
    });
 
      // Create an empty vector to store the points on the convex hull
    vector<Point> hull;
   
      // Add points to the convex hull one by one
    for (int i = 0; i < n; i++) {
       
          // Check if the last two points and the new point make a left turn
        while (hull.size() >= 2 && absArea(hull[hull.size()-2],
                                           hull.back(), points[i]) <= EPS) {
               
              // If not, remove the last point from the convex hull
            hull.pop_back();
        }
       
          // Add the new point to the convex hull
        hull.push_back(points[i]);
    }
 
      // Repeat the same process for the lower part of the convex hull
    for (int i = n - 2, t = hull.size() + 1; i >= 0; i--) {
       
        while (hull.size() >= t && absArea(hull[hull.size()-2],
                                           hull.back(), points[i]) <= EPS)
        {
            hull.pop_back();
        }
        hull.push_back(points[i]);
    }
 
      // Return the convex hull
    return hull;
}
 
// A function to calculate the width of the smallest bounding rectangle
double rotatingCaliper(vector<Point>& points) {
   
      // Calculate the convex hull of the set
    vector<Point> hull = convexHull(points);
    int n = hull.size();
 
      // If the convex hull has only one point, the width is 0
    if (n == 1) return 0;
   
      // If the convex hull has two points, the width
      // is the distance between the two points
    if (n == 2) return sqrt(dist(hull[0], hull[1]));
 
    int k = 1;
   
    while (absArea(hull[n-1], hull[0], hull[(k+1)%n]) >
           absArea(hull[n-1], hull[0], hull[k]))
    {
        k++;
    }
 
    double res = 0;
   
    for (int i = 0, j = k; i <= k; i++) {
       
        while (absArea(hull[i], hull[(i+1)%n], hull[(j+1)%n]) >
               absArea(hull[i], hull[(i+1)%n], hull[j]))
        {
            res = max(res, sqrt(dist(hull[i], hull[(j+1)%n])));
            j = (j+1) % n;
        }
       
        res = max(res, sqrt(dist(hull[i], hull[j])));
    }
 
    return res;
}
 
// Driver code
int main() {
    vector<Point> points = { Point(4, 0),
                            Point(0, 2),
                            Point(-1, -7),
                            Point(1, 10),
                            Point(2, -3) };
   
    cout << fixed << setprecision(14) << rotatingCaliper(points) << endl;
    return 0;
}
 
// This code is contributed by amit_mangal_

                    
// Java Program for the above approach
import java.awt.*;
import java.util.*;
import java.util.Map.Entry;
 
public class Main {
 
    // Function to detect the orientation
    static int orientation(Point p,
                           Point q,
                           Point r)
    {
        int x = area(p, q, r);
 
        // If area > 0 then
        // points are clockwise
        if (x > 0) {
            return 1;
        }
 
        // If area<0 then
        // points are counterclockwise
        if (x < 0) {
            return -1;
        }
 
        // If area is 0 then p, q
        // and r are co-linear
        return 0;
    }
 
    // Function to find the area
    static int area(Point p, Point q, Point r)
    {
        // 2*(area of triangle)
        return ((p.y - q.y) * (q.x - r.x)
                - (q.y - r.y) * (p.x - q.x));
    }
 
    // Function to find the absolute Area
    static int absArea(Point p,
                       Point q, Point r)
    {
        // Unsigned area
        // 2*(area of triangle)
        return Math.abs(area(p, q, r));
    }
 
    // Function to find the distance
    static int dist(Point p1, Point p2)
    {
        // squared-distance b/w
        // p1 and p2 for precision
        return ((p1.x - p2.x) * (p1.x - p2.x)
                + (p1.y - p2.y) * (p1.y - p2.y));
    }
 
    // Function to implement Convex Hull
    // Approach
    static ArrayList<Point>
    convexHull(Point points[])
    {
        int n = points.length;
 
        Point min = new Point(Integer.MAX_VALUE,
                              Integer.MAX_VALUE);
 
        // Choose point having min.
        // y-coordinate and if two points
        // have same y-coordinate choose
        // the one with minimum x-coordinate
        int ind = -1;
 
        // Iterate Points[]
        for (int i = 0; i < n; i++) {
            if (min.y > points[i].y) {
                min.y = points[i].y;
                min.x = points[i].x;
                ind = i;
            }
            else if (min.y == points[i].y
                     && min.x > points[i].x) {
                min.x = points[i].x;
                ind = i;
            }
        }
        points[ind] = points[0];
        points[0] = min;
 
        // Sort points which have
        // minimum polar angle wrt
        // Point min
        Arrays.sort(points, 1, n,
                    new Comparator<Point>() {
 
                        @Override
                        public int compare(Point o1,
                                           Point o2)
                        {
 
                            int o = orientation(min, o1, o2);
 
                            // If points are co-linear
                            // choose the one having smaller
                            // distance with min first.
                            if (o == 0) {
                                return dist(o1, min)
                                    - dist(o2, min);
                            }
 
                            // If clockwise then swap
                            if (o == 1) {
                                return 1;
                            }
 
                            // If anticlockwise then
                            // don't swap
                            return -1;
                        }
                    });
 
        Stack<Point> st = new Stack<>();
 
        // First hull point
        st.push(points[0]);
 
        int k;
        for (k = 1; k < n - 1; k++) {
            if (orientation(points[0],
                            points[k],
                            points[k + 1])
                != 0)
                break;
        }
 
        // Second hull point
        st.push(points[k]);
 
        for (int i = k + 1; i < n; i++) {
            Point top = st.pop();
 
            while (orientation(st.peek(),
                               top,
                               points[i])
                   >= 0) {
                top = st.pop();
            }
 
            st.push(top);
            st.push(points[i]);
        }
 
        ArrayList<Point> hull
            = new ArrayList<>();
 
        // Iterate stack and add node to hull
        for (int i = 0; i < st.size(); i++) {
            hull.add(st.get(i));
        }
        return hull;
    }
 
    // Function to find the maximum
    // distance between any two points
    // from a set of given points
    static double
    rotatingCaliper(Point points[])
    {
        // Takes O(n)
        ArrayList<Point> convexHull
            = convexHull(points);
        int n = convexHull.size();
 
        // Convex hull point in counter-
        // clockwise order
        Point hull[] = new Point[n];
        n = 0;
 
        while (n < convexHull.size()) {
            hull[n] = convexHull.get(n++);
        }
 
        // Base Cases
        if (n == 1)
            return 0;
        if (n == 2)
            return Math.sqrt(dist(hull[0], hull[1]));
        int k = 1;
 
        // Find the farthest vertex
        // from hull[0] and hull[n-1]
        while (absArea(hull[n - 1],
                       hull[0],
                       hull[(k + 1) % n])
               > absArea(hull[n - 1],
                         hull[0],
                         hull[k])) {
            k++;
        }
 
        double res = 0;
 
        // Check points from 0 to k
        for (int i = 0, j = k;
             i <= k && j < n; i++) {
            res = Math.max(res,
                           Math.sqrt((double)dist(hull[i],
                                                  hull[j])));
 
            while (j < n
                   && absArea(hull[i],
                              hull[(i + 1) % n],
                              hull[(j + 1) % n])
                          > absArea(hull[i],
                                    hull[(i + 1) % n],
                                    hull[j])) {
 
                // Update res
                res = Math.max(
                    res,
                    Math.sqrt(dist(hull[i],
                                   hull[(j + 1) % n])));
                j++;
            }
        }
 
        // Return the result distance
        return res;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        // Total points
        int n = 5;
        Point p[] = new Point[n];
 
        // Given Points
        p[0] = new Point(4, 0);
        p[1] = new Point(0, 2);
        p[2] = new Point(-1, -7);
        p[3] = new Point(1, 10);
        p[4] = new Point(2, -3);
 
        // Function Call
        System.out.println(rotatingCaliper(p));
    }
}

                    
import math
 
# Define a class to represent a point
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
 
# Function to calculate the
# squared Euclidean distance between two points
def dist(p, q):
    return (p.x - q.x) ** 2 + (p.y - q.y) ** 2
 
# Function to calculate the
# absolute area of a triangle formed by three points
def absArea(p, q, r):
    return abs((p.x * q.y + q.x * r.y + r.x * p.y) -
               (p.y * q.x + q.y * r.x + r.y * p.x))
 
# Function to calculate the
# cross product of two vectors formed by three points
def crossProduct(p, q, r):
    return ((q.x - p.x) * (r.y - p.y)) - ((q.y - p.y) * (r.x - p.x))
 
# Function to calculate the convex hull
# of a list of points using the Graham scan algorithm
def convexHull(points):
   
    # Sort the points lexicographically by their x-coordinates,
    # breaking ties by their y-coordinates
    points.sort(key=lambda p: (p.x, p.y))
 
    hull = []
    n = len(points)
     
    # Traverse the sorted points from left to right
    for i in range(n):
       
        # Remove any point from the hull that makes a
        # clockwise turn with the previous two points on the hull
        while len(hull) >= 2 and crossProduct(hull[-2], hull[-1], points[i]) <= 0:
            hull.pop()
             
        hull.append(points[i])
 
    # Traverse the sorted points from right to left
    for i in range(n - 2, -1, -1):
       
        # Remove any point from the hull that makes a
        # clockwise turn with the previous two points on the hull
        while len(hull) >= 2 and crossProduct(hull[-2], hull[-1], points[i]) <= 0:
            hull.pop()
             
        hull.append(points[i])
 
    # Return the hull, omitting the last point, which is the same as the first point
    return hull[:-1]
 
def rotatingCaliper(points):
   
    # Takes O(n)
    convex_hull_points = convexHull(points)
    n = len(convex_hull_points)
 
    # Convex hull point in counter-clockwise order
    hull = []
    for i in range(n):
        hull.append(convex_hull_points[i])
 
    # Base Cases
    if n == 1:
        return 0
    if n == 2:
        return math.sqrt(dist(hull[0], hull[1]))
    k = 1
 
    # Find the farthest vertex
    # from hull[0] and hull[n-1]
    while crossProduct(hull[n - 1], hull[0], hull[(k + 1) % n]) > crossProduct(hull[n - 1], hull[0], hull[k]):
        k += 1
 
    res = 0
 
    # Check points from 0 to k
    for i in range(k + 1):
        j = (i + 1) % n
        while crossProduct(hull[i], hull[(i + 1) % n], hull[(j + 1) % n]) > crossProduct(hull[i], hull[(i + 1) % n], hull[j]):
            # Update res
            res = max(res, math.sqrt(dist(hull[i], hull[(j + 1) % n])))
            j = (j + 1) % n
 
    # Return the result distance
    return res
 
 
# Driver Code
if __name__ == '__main__':
   
    # Total points
    n = 5
    p = []
     
    # Given Points
    p.append(Point(4, 0))
    p.append(Point(0, 2))
    p.append(Point(-1, -7))
    p.append(Point(1, 10))
    p.append(Point(2, -3))
     
    # Function Call
    print(rotatingCaliper(p))
     
# This code is contributed by amit_mangal_

                    
using System;
using System.Collections.Generic;
 
class Point
{
    public double x;
    public double y;
 
    public Point(double x, double y)
    {
        this.x = x;
        this.y = y;
    }
}
 
class Program
{
    // Function to calculate the squared Euclidean distance between two points
    static double Dist(Point p, Point q)
    {
        return Math.Pow(p.x - q.x, 2) + Math.Pow(p.y - q.y, 2);
    }
 
    // Function to calculate the absolute area of a triangle formed by three points
    static double AbsArea(Point p, Point q, Point r)
    {
        return Math.Abs((p.x * q.y + q.x * r.y + r.x * p.y) - (p.y * q.x + q.y * r.x + r.y * p.x));
    }
 
    // Function to calculate the cross product of two vectors formed by three points
    static double CrossProduct(Point p, Point q, Point r)
    {
        return ((q.x - p.x) * (r.y - p.y)) - ((q.y - p.y) * (r.x - p.x));
    }
 
    // Function to calculate the convex hull of a list of points using the Graham scan algorithm
    static List<Point> ConvexHull(List<Point> points)
    {
        points.Sort((p1, p2) => p1.x == p2.x ? p1.y.CompareTo(p2.y) : p1.x.CompareTo(p2.x));
 
        List<Point> hull = new List<Point>();
        int n = points.Count;
 
        for (int i = 0; i < n; i++)
        {
            while (hull.Count >= 2 && CrossProduct(hull[hull.Count - 2], hull[hull.Count - 1], points[i]) <= 0)
            {
                hull.RemoveAt(hull.Count - 1);
            }
 
            hull.Add(points[i]);
        }
 
        int upperHullSize = hull.Count;
 
        for (int i = n - 2; i >= 0; i--)
        {
            while (hull.Count > upperHullSize && CrossProduct(hull[hull.Count - 2], hull[hull.Count - 1], points[i]) <= 0)
            {
                hull.RemoveAt(hull.Count - 1);
            }
 
            hull.Add(points[i]);
        }
 
        return hull;
    }
 
    // Function to compute the rotating calipers for the convex hull
    static double RotatingCaliper(List<Point> points)
    {
        List<Point> convexHullPoints = ConvexHull(points);
        int n = convexHullPoints.Count;
        List<Point> hull = new List<Point>(convexHullPoints);
 
        if (n == 1)
        {
            return 0;
        }
        if (n == 2)
        {
            return Math.Sqrt(Dist(hull[0], hull[1]));
        }
 
        int k = 1;
        while (CrossProduct(hull[n - 1], hull[0], hull[(k + 1) % n]) > CrossProduct(hull[n - 1], hull[0], hull[k]))
        {
            k++;
        }
 
        double res = 0;
 
        for (int i = 0; i <= k; i++)
        {
            int j = (i + 1) % n;
            while (CrossProduct(hull[i], hull[(i + 1) % n], hull[(j + 1) % n]) > CrossProduct(hull[i], hull[(i + 1) % n], hull[j]))
            {
                res = Math.Max(res, Math.Sqrt(Dist(hull[i], hull[(j + 1) % n])));
                j = (j + 1) % n;
            }
        }
 
        return res;
    }
 
    static void Main()
    {
        List<Point> points = new List<Point>();
 
        // Given Points
        points.Add(new Point(4, 0));
        points.Add(new Point(0, 2));
        points.Add(new Point(-1, -7));
        points.Add(new Point(1, 10));
        points.Add(new Point(2, -3));
 
        // Function Call
        double result = RotatingCaliper(points);
        Console.WriteLine(result);
    }
}

                    
// A small constant to handle precision errors
const EPS = 1e-9;
 
// A class to represent a 2D point
class Point {
  constructor(x = 0, y = 0) {
    this.x = x;
    this.y = y;
  }
}
 
// A function to calculate the squared distance between two points
function dist(p, q) {
  return (p.x - q.x) ** 2 + (p.y - q.y) ** 2;
}
 
// A function to calculate the absolute area of a triangle
function absArea(p, q, r) {
  return Math.abs(
    p.x * q.y + q.x * r.y + r.x * p.y - (p.y * q.x + q.y * r.x + r.y * p.x)
  );
}
 
// A function to calculate the convex hull of a set of points
function convexHull(points) {
  const n = points.length;
 
  // Sort the points by x-coordinate (in case of a tie, by y-coordinate)
  points.sort((a, b) => {
    if (a.x !== b.x) return a.x - b.x;
    return a.y - b.y;
  });
 
  // Create an empty array to store the points on the convex hull
  const hull = [];
 
  // Add points to the convex hull one by one
  for (let i = 0; i < n; i++) {
    // Check if the last two points and the new point make a left turn
    while (
      hull.length >= 2 &&
      absArea(hull[hull.length - 2], hull[hull.length - 1], points[i]) <= EPS
    ) {
      // If not, remove the last point from the convex hull
      hull.pop();
    }
 
    // Add the new point to the convex hull
    hull.push(points[i]);
  }
 
  // Repeat the same process for the lower part of the convex hull
  for (let i = n - 2, t = hull.length + 1; i >= 0; i--) {
    while (
      hull.length >= t &&
      absArea(hull[hull.length - 2], hull[hull.length - 1], points[i]) <= EPS
    ) {
      hull.pop();
    }
    hull.push(points[i]);
  }
 
  // Return the convex hull
  return hull;
}
 
// A function to calculate the width of the smallest bounding rectangle
function rotatingCaliper(points) {
  // Calculate the convex hull of the set
  const hull = convexHull(points);
  const n = hull.length;
 
  // If the convex hull has only one point, the width is 0
  if (n === 1) return 0;
 
  // If the convex hull has two points, the width is the distance between the two points
  if (n === 2) return Math.sqrt(dist(hull[0], hull[1]));
 
  let k = 1;
 
  while (
    absArea(hull[n - 1], hull[0], hull[(k + 1) % n]) >
    absArea(hull[n - 1], hull[0], hull[k])
  ) {
    k++;
  }
 
  let res = 0;
 
  for (let i = 0, j = k; i <= k; i++) {
    while (
      absArea(hull[i], hull[(i + 1) % n], hull[(j + 1) % n]) >
      absArea(hull[i], hull[(i + 1) % n], hull[j])
    ) {
      res = Math.max(res, Math.sqrt(dist(hull[i], hull[(j + 1) % n])));
      j = (j + 1) % n;
    }
 
    res = Math.max(res, Math.sqrt(dist(hull[i], hull[j])));
  }
 
  return res;
}
 
// Driver code
const points = [
  new Point(4, 0),
  new Point(0, 2),
  new Point(-1, -7),
  new Point(1, 10),
  new Point(2, -3),
];
 
console.log(rotatingCaliper(points).toFixed(14));

                    

Output
17.11724276862369


Time Complexity: O(N*log N) 
Auxiliary Space: O(N)
 


Article Tags :