Convex Hull (Graham's Scan, Jarvis March) - CSU083 | Shoolini University

Convex Hull (Graham’s Scan, Jarvis March)

1. Prerequisites

Before understanding Convex Hull algorithms, you must be familiar with:

2. What is Convex Hull?

The Convex Hull of a set of points is the smallest convex polygon that encloses all the points.

3. Why does this algorithm exist?

Convex Hull has practical applications in various domains:

4. When should you use it?

Choose Convex Hull when:

5. How does it compare to alternatives?

Comparison of Convex Hull Algorithms:

5.1 Graham’s Scan

5.2 Jarvis March

5.3 Alternative Algorithms

6. Basic Implementation

Below is the Python implementation of Convex Hull using Graham’s Scan and Jarvis March.

6.1 Graham’s Scan (O(n log n))

import math

def cross_product(o, a, b):
    return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0])

def graham_scan(points):
    points = sorted(points)  # Sort points lexicographically
    lower, upper = [], []

    # Construct lower hull
    for p in points:
        while len(lower) >= 2 and cross_product(lower[-2], lower[-1], p) <= 0:
            lower.pop()
        lower.append(p)

    # Construct upper hull
    for p in reversed(points):
        while len(upper) >= 2 and cross_product(upper[-2], upper[-1], p) <= 0:
            upper.pop()
        upper.append(p)

    return lower[:-1] + upper[:-1]  # Remove duplicate endpoints

# Sample Input
points = [(0, 0), (1, 1), (2, 2), (0, 2), (2, 0), (1, 2), (2, 1)]
print(graham_scan(points))  # Expected Convex Hull Output

6.2 Jarvis March (O(nh))

def jarvis_march(points):
    if len(points) < 3:
        return points  # Convex hull not possible with less than 3 points

    hull = []
    leftmost = min(points)  # Start from the leftmost point
    point_on_hull = leftmost

    while True:
        hull.append(point_on_hull)
        next_point = points[0]

        for candidate in points:
            if candidate == point_on_hull:
                continue
            direction = cross_product(point_on_hull, next_point, candidate)
            if direction > 0 or (direction == 0 and 
                                 math.dist(point_on_hull, candidate) > math.dist(point_on_hull, next_point)):
                next_point = candidate
        
        point_on_hull = next_point
        if point_on_hull == leftmost:
            break  # Completed the hull

    return hull

# Sample Input
points = [(0, 0), (1, 1), (2, 2), (0, 2), (2, 0), (1, 2), (2, 1)]
print(jarvis_march(points))  # Expected Convex Hull Output

7. Dry Run

7.1 Input Set

Given points: (0,0), (1,1), (2,2), (0,2), (2,0), (1,2), (2,1)

7.2 Graham’s Scan Execution

7.3 Jarvis March Execution

8. Time & Space Complexity Analysis

8.1 Graham’s Scan Complexity

Breakdown:

8.2 Jarvis March Complexity

Breakdown:

9. Space Complexity Analysis

9.1 Graham’s Scan

9.2 Jarvis March

9.3 Space Growth with Input Size

10. Trade-offs & Comparison

10.1 When to Use Graham’s Scan?

10.2 When to Use Jarvis March?

10.3 General Comparison

Algorithm Time Complexity Space Complexity Best Use Case
Graham’s Scan O(n log n) O(n) Large n, small h
Jarvis March O(nh) (Worst O(n²)) O(n) Small h, large n

10.4 Key Takeaways

11. Optimizations & Variants

11.1 Common Optimizations

11.2 Variants of Convex Hull Algorithms

11.2.1 Monotone Chain (Andrew’s Algorithm)
11.2.2 QuickHull (Divide & Conquer Approach)
11.2.3 Kirkpatrick-Seidel Algorithm (Ultimate Optimization)

12. Iterative vs. Recursive Implementations

12.1 Iterative Approach

12.2 Recursive Approach

12.3 Comparison Table

Approach Memory Usage Performance Best Use Case
Iterative O(n) (uses stack) Generally faster Graham’s Scan, Monotone Chain
Recursive O(n) + call stack overhead Can be slower QuickHull, Kirkpatrick-Seidel

12.4 Key Takeaways

13. Edge Cases & Failure Handling

13.1 Common Pitfalls & Edge Cases

14. Test Cases to Verify Correctness

14.1 Basic Test Cases


def test_convex_hull():
    points1 = [(0, 0), (1, 1), (2, 2), (0, 2), (2, 0)]
    assert graham_scan(points1) == [(0, 0), (2, 0), (2, 2), (0, 2)]
    assert jarvis_march(points1) == [(0, 0), (2, 0), (2, 2), (0, 2)]

    points2 = [(1, 1), (2, 2), (3, 3)]
    assert graham_scan(points2) == [(1, 1), (3, 3)]
    assert jarvis_march(points2) == [(1, 1), (3, 3)]

    points3 = [(0, 0), (0, 0), (1, 1), (1, 1)]
    assert graham_scan(points3) == [(0, 0), (1, 1)]
    assert jarvis_march(points3) == [(0, 0), (1, 1)]

    points4 = [(0, 0), (2, 0), (2, 2), (0, 2), (1, 1)]
    assert graham_scan(points4) == [(0, 0), (2, 0), (2, 2), (0, 2)]
    assert jarvis_march(points4) == [(0, 0), (2, 0), (2, 2), (0, 2)]
    
    print("All test cases passed!")

test_convex_hull()

14.2 Edge Case Test Cases

15. Real-World Failure Scenarios

15.1 Failure Due to Floating-Point Precision

Floating-point calculations can cause rounding errors, affecting the cross-product test.

15.2 Failure Due to High Complexity on Large Datasets

Jarvis March runs in O(nh), which can become O(n²) for large convex hulls, making it inefficient.

15.3 Failure in Real-World Mapping Applications

Convex hull algorithms are often used in GIS applications to create geographical boundaries. However, errors arise when handling:

Fix: Use spatial clustering before computing the convex hull.

15.4 Handling of Duplicate or Redundant Points

If input data has duplicates, naive implementations might add them to the hull.

16. Real-World Applications & Industry Use Cases

Convex Hull algorithms are widely used in multiple fields for geometric and optimization tasks. Some key applications include:

16.1 Computer Vision & Image Processing

16.2 Geographic Information Systems (GIS)

16.3 Robotics & Path Planning

16.4 Machine Learning & Data Science

16.5 Game Development

16.6 Computational Geometry & Physics Simulations

17. Open-Source Implementations

Convex Hull algorithms have been implemented in various open-source libraries:

17.1 SciPy (Python)

17.2 OpenCV (C++/Python)

17.3 CGAL (Computational Geometry Algorithms Library - C++)

18. Project: Convex Hull for GPS-Based Geofencing

We will create a Python script that takes real-world GPS coordinates and computes a convex hull to define a geofenced area.

18.1 Project Overview

18.2 Implementation


import matplotlib.pyplot as plt
from scipy.spatial import ConvexHull
import numpy as np

# Sample GPS coordinates (latitude, longitude)
locations = np.array([
    [28.6139, 77.2090],  # New Delhi
    [19.0760, 72.8777],  # Mumbai
    [13.0827, 80.2707],  # Chennai
    [22.5726, 88.3639],  # Kolkata
    [26.8467, 80.9462],  # Lucknow
    [21.1702, 72.8311],  # Surat
    [23.0225, 72.5714],  # Ahmedabad
])

# Compute Convex Hull
hull = ConvexHull(locations)

# Plot the points and the convex hull
plt.scatter(locations[:, 0], locations[:, 1], label="Cities")

# Draw the convex hull
for simplex in hull.simplices:
    plt.plot(locations[simplex, 0], locations[simplex, 1], 'r-')

plt.xlabel("Latitude")
plt.ylabel("Longitude")
plt.title("Geofenced Region using Convex Hull")
plt.legend()
plt.show()

18.3 Expected Output

The script plots the geofenced region, forming a convex boundary around major cities.

18.4 Potential Enhancements

19. Competitive Programming & System Design Integration

19.1 Competitive Programming Applications

Convex Hull algorithms are frequently used in competitive programming to solve problems involving geometry, optimization, and data structures. Key applications include:

19.2 System Design Integration

Convex Hulls are not just theoretical but play a key role in large-scale systems. Some real-world system integrations include:

19.2.1 Autonomous Vehicles
19.2.2 Cloud-Based GIS Systems
19.2.3 AI and Game Development

20. Assignments & Practice Problems

20.1 Solve at Least 10 Problems Using Convex Hull

These problems will help reinforce the application of convex hull algorithms:

  1. [Easy] Smallest Enclosing Convex Polygon: Given n points, find the convex hull. (SPOJ BSHEEP)
  2. [Easy] Checking Point Inside Convex Hull: Given a convex hull and a new point, determine if it lies inside. (Codeforces 1284B)
  3. [Medium] Maximum Euclidean Distance in a Hull: Find the two farthest points in a convex hull. (Rotating calipers technique)
  4. [Medium] Minimum Perimeter Fence: Compute the perimeter of a convex hull. (SPOJ FENCE1)
  5. [Medium] Convex Hull Trick: Optimize a DP problem using a convex hull. (Convex Hull Trick Tutorial)
  6. [Hard] 2D Minkowski Sum: Given two polygons, compute their Minkowski sum.
  7. [Hard] K-Closest Points to a Convex Hull: Find the k nearest points to a given convex hull.
  8. [Hard] Dynamic Convex Hull: Update a convex hull as points are added/removed. (Codeforces 319C)
  9. [Hard] Minimum Convex Partition: Partition a set of points into the fewest convex sets.
  10. [Expert] 3D Convex Hull: Implement convex hull computation in 3D. (GeeksforGeeks)

20.2 System Design Problem Using Convex Hull

Design a geospatial-based application that uses Convex Hull for:

Deliverables:

20.3 Implement Under Time Constraints

To simulate a competitive programming environment, practice:

20.4 Evaluation Metrics