Thursday, October 9, 2025
HomeData Modelling & AIComputational Geometry – Algorithms for Geometry

Computational Geometry – Algorithms for Geometry

Computational geometry is a field of study that focuses on developing algorithms and data structures for solving problems that involve geometric shapes and structures. The field has applications in a variety of areas, including computer graphics, robotics, geographic information systems, and more.

In this article, we will explore some of the key concepts and applications of computational geometry.

Geometric Problems:

One of the key goals of computational geometry is to find efficient solutions to geometric problems that arise in various fields. Some common geometric problems include:

  • The intersection of two lines or planes
  • Convex hull of a set of points
  • Triangulation of a polygon
  • Voronoi diagram of a set of points
  • Delaunay triangulation of a set of points
  • Point location in a planar subdivision 

The solution to these Geometric Problems:

To solve these problems, computational geometry uses a variety of algorithms and data structures, the most commonly used algorithms include:

1) Sweep line algorithm:

A method for solving a wide range of geometric problems, including computing the intersection of two lines or planes and triangulating a polygon. The algorithm works by sweeping a line or plane across the geometry and updating a data structure as it goes.

Use Cases:

  • Closest pair of points problem: Finding the closest pair of points among a set of points in a 2D plane.
  • Line segment intersection problem: Finding whether two or more line segments intersect in a 2D plane.
  • Rectangle intersection problem: Finding whether two or more rectangles intersect in a 2D plane.
  • Bentley-Ottmann algorithm: Computing the intersection of line segments in a plane.

Line segment intersection problem using Sweep line algorithm:

C++




// C++ code to implement the sweep
// line algorithm
#include <bits/stdc++.h>
using namespace std;
 
struct Point {
    double x, y;
};
 
struct Line {
    Point p, q;
};
 
// Function to check if two
// lines intersect
bool doIntersect(Line l1, Line l2)
{
 
    // Implementation of intersection
    // checking algorithm
}
 
// Function to compute the intersection
// point of two lines
Point computeIntersection(Line l1, Line l2)
{
    double x1 = l1.p.x, y1 = l1.p.y;
    double x2 = l1.q.x, y2 = l1.q.y;
    double x3 = l2.p.x, y3 = l2.p.y;
    double x4 = l2.q.x, y4 = l2.q.y;
 
    double denom
        = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
    double num1
        = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3);
    double num2
        = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3);
 
    if (denom == 0) {
 
        // Lines are parallel
        return { INFINITY, INFINITY };
    }
 
    double ua = num1 / denom;
    double ub = num2 / denom;
 
    if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1) {
 
        // Intersection point lies on
        // both line segments
        double x = x1 + ua * (x2 - x1);
        double y = y1 + ua * (y2 - y1);
        return { x, y };
    }
 
    // Lines do not intersect
    return { INFINITY, INFINITY };
}
 
// Driver's code
int main()
{
    Line l1 = { { 0, 0 }, { 1, 1 } };
    Line l2 = { { 0, 1 }, { 1, 0 } };
 
    if (doIntersect(l1, l2)) {
 
        // Function call
        Point p = computeIntersection(l1, l2);
        cout << "Intersection point: (" << p.x << ", "
             << p.y << ")" << endl;
    }
    else {
        cout << "Lines do not intersect" << endl;
    }
 
    return 0;
}


Python




# Python Code to implement the Sweep Line Algorithm
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
 
class Line:
    def __init__(self, p, q):
        self.p = p
        self.q = q
 
def doIntersect(l1, l2):
    # Implementation of intersection checking algorithm
    pass  # You can implement this function as needed
 
def computeIntersection(l1, l2):
    x1, y1 = l1.p.x, l1.p.y
    x2, y2 = l1.q.x, l1.q.y
    x3, y3 = l2.p.x, l2.p.y
    x4, y4 = l2.q.x, l2.q.y
 
    denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)
    num1 = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)
    num2 = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)
 
    if denom == 0:
        # Lines are parallel
        return float('inf'), float('inf')
 
    ua = num1 / denom
    ub = num2 / denom
 
    if 0 <= ua <= 1 and 0 <= ub <= 1:
        # Intersection point lies on both line segments
        x = x1 + ua * (x2 - x1)
        y = y1 + ua * (y2 - y1)
        return x, y
 
    # Lines do not intersect
    return float('inf'), float('inf')
 
# Driver's code
if __name__ == "__main__":
    l1 = Line(Point(0, 0), Point(1, 1))
    l2 = Line(Point(0, 1), Point(1, 0))
 
    if doIntersect(l1, l2):
        # Function call
        p = computeIntersection(l1, l2)
        print("Intersection point: ({}, {})".format(p[0], p[1]))
    else:
        print("Lines do not intersect")


Output

Lines do not intersect

Limitations of the Sweep line algorithm:

  • The sweep line algorithm assumes that the objects being swept are not overlapping in the same event point. If this assumption is violated, the algorithm may fail.
  • The algorithm may require sorting and searching operations that have a high computational cost.

2) Graham Scan Algorithm:

  • Graham scan is a well-known algorithm in computational geometry that is used to find the convex hull of a given set of points. The algorithm was proposed by Ronald Graham in 1972.
  • The basic idea of the algorithm is to start with the point with the lowest y-coordinate (and lowest x-coordinate in case of a tie), and then sort the remaining points in order of the angle they make with the horizontal line passing through the starting point. This can be done using the polar angle of each point with respect to the starting point.
  • Once the points are sorted, the algorithm proceeds in a clockwise direction around the points, adding each point to the convex hull if it does not create a counter-clockwise turn with the last two points in the hull. If it does create a counter-clockwise turn, then the last point added to the hull is removed, and the process is repeated until the new point does not create a counter-clockwise turn.
  • The Graham scan algorithm has a time complexity of O(n log n), where n is the number of input points. The algorithm is widely used in applications such as computer graphics, geographic information systems, and robotics.

Use Cases:

  • Convex hull problem: Finding the convex hull of a set of points in a 2D plane.
  • Rotating calipers algorithm: Finding the width and diameter of a convex polygon.
  • Maximum distance problem: Finding the maximum distance between any two points in a set of points in a 2D plane.

Let’s see the implementation of Graham’s algorithm for the convex hull problem:

C++




// C++ code to implement the graham
// scan algorithm
#include <algorithm>
#include <iostream>
#include <stack>
#include <vector>
 
using namespace std;
 
struct Point {
    int x, y;
};
 
Point p0;
 
// Comparator function for sorting points
// in counterclockwise order around p0
int compare(const void* vp1, const void* vp2)
{
    Point* p1 = (Point*)vp1;
    Point* p2 = (Point*)vp2;
 
    int orientation = (p1->y - p0.y) * (p2->x - p1->x)
                      - (p1->x - p0.x) * (p2->y - p1->y);
 
    if (orientation == 0) {
        return (p1->x + p1->y < p2->x + p2->y) ? -1 : 1;
    }
 
    return (orientation < 0) ? -1 : 1;
}
 
// Returns the square of the Euclidean
// distance between two points
int distSq(Point p1, Point p2)
{
    return (p2.x - p1.x) * (p2.x - p1.x)
           + (p2.y - p1.y) * (p2.y - p1.y);
}
 
// Returns the orientation of three
// points (p, q, r)
int orientation(Point p, Point q, Point r)
{
    int val = (q.y - p.y) * (r.x - q.x)
              - (q.x - p.x) * (r.y - q.y);
 
    if (val == 0) {
        return 0;
    }
 
    return (val > 0) ? 1 : 2;
}
 
// Computes the convex hull of a set of n
// points using the Graham's
// Scan algorithm
void convexHull(Point points[], int n)
{
 
    // Find the point with the
    // lowest y-coordinate
    int ymin = points[0].y;
    int min = 0;
    for (int i = 1; i < n; i++) {
        int y = points[i].y;
 
        if ((y < ymin)
            || (ymin == y && points[i].x < points[min].x)) {
            ymin = points[i].y;
            min = i;
        }
    }
 
    // Swap the lowest point with
    // the first point
    swap(points[0], points[min]);
    p0 = points[0];
 
    // Sort the remaining points in
    // counterclockwise order around p0
    qsort(&points[1], n - 1, sizeof(Point), compare);
 
    // If two or more points have the same
    // angle with p0, remove all but
    // the farthest
    int m = 1;
    for (int i = 1; i < n; i++) {
        while (i < n - 1
               && orientation(p0, points[i], points[i + 1])
                      == 0) {
            i++;
        }
 
        points[m] = points[i];
        m++;
    }
 
    // If there are less than 3 unique
    // points, there is no convex hull
    if (m < 3) {
        return;
    }
 
    // Use a stack to keep track of the
    // vertices of the convex hull
    stack<Point> hull;
    hull.push(points[0]);
    hull.push(points[1]);
    hull.push(points[2]);
 
    // Process the remaining points
    for (int i = 3; i < n; i++) {
        while (hull.size() > 1
               && orientation(hull.top(), hull.top(),
                              points[i])
                      != 2) {
            hull.pop();
        }
 
        hull.push(points[i]);
    }
 
    // Print the vertices of the
    // convex hull
    while (!hull.empty()) {
        Point p = hull.top();
        cout << "(" << p.x << ", " << p.y << ")" << endl;
        hull.pop();
    }
}
 
// Driver's code
int main()
{
 
    // Test the algorithm with a set of points
    Point points[]
        = { { 0, 3 }, { 1, 1 }, { 2, 2 }, { 4, 4 }, { 0, 0 }, { 1, 2 }, { 3, 1 }, { 3, 3 } };
    int n = sizeof(points) / sizeof(points[0]);
 
    cout << "Vertices of the convex hull:" << endl;
    convexHull(points, n);
 
    return 0;
}


Output

Vertices of the convex hull:
(0, 3)
(0, 0)

Limitations of the Graham scan algorithm:

  • The Graham scan algorithm only works for 2D convex hull problems.
  • The algorithm has a computational complexity of O(n*logn), which can be a limiting factor for large datasets.
  • The algorithm is sensitive to degenerate cases where many points lie in a straight line.
Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

RELATED ARTICLES

Most Popular

Dominic
32342 POSTS0 COMMENTS
Milvus
87 POSTS0 COMMENTS
Nango Kala
6712 POSTS0 COMMENTS
Nicole Veronica
11876 POSTS0 COMMENTS
Nokonwaba Nkukhwana
11937 POSTS0 COMMENTS
Shaida Kate Naidoo
6833 POSTS0 COMMENTS
Ted Musemwa
7092 POSTS0 COMMENTS
Thapelo Manthata
6786 POSTS0 COMMENTS
Umr Jansen
6789 POSTS0 COMMENTS