Computational Geometry: Points, Lines, and Convex Hull

Sanjeev SharmaSanjeev Sharma
3 min read

Advertisement

Computational Geometry

Cross Product

For vectors AB and AC:

cross(AB, AC) = (B.x-A.x)*(C.y-A.y) - (B.y-A.y)*(C.x-A.x)
  • Positive: C is to the left of AB (counterclockwise)
  • Negative: C is to the right of AB (clockwise)
  • Zero: collinear

Python Implementation

def cross(O, A, B):
    return (A[0]-O[0])*(B[1]-O[1]) - (A[1]-O[1])*(B[0]-O[0])

def dot(A, B):
    return A[0]*B[0] + A[1]*B[1]

def dist2(A, B):  # squared distance (integer, avoids float)
    return (A[0]-B[0])**2 + (A[1]-B[1])**2

# Check if point P is on segment AB
def on_segment(A, B, P):
    if cross(A, B, P) != 0: return False
    return (min(A[0],B[0]) <= P[0] <= max(A[0],B[0]) and
            min(A[1],B[1]) <= P[1] <= max(A[1],B[1]))

# Check if segments AB and CD intersect
def segments_intersect(A, B, C, D):
    d1 = cross(C, D, A)
    d2 = cross(C, D, B)
    d3 = cross(A, B, C)
    d4 = cross(A, B, D)
    if ((d1>0 and d2<0) or (d1<0 and d2>0)) and        ((d3>0 and d4<0) or (d3<0 and d4>0)):
        return True
    if d1==0 and on_segment(C, D, A): return True
    if d2==0 and on_segment(C, D, B): return True
    if d3==0 and on_segment(A, B, C): return True
    if d4==0 and on_segment(A, B, D): return True
    return False

# Convex Hull: Graham Scan O(n log n)
def convex_hull(points):
    points = sorted(set(points))
    if len(points) <= 1: return points
    def build(pts):
        hull = []
        for p in pts:
            while len(hull) >= 2 and cross(hull[-2], hull[-1], p) <= 0:
                hull.pop()
            hull.append(p)
        return hull
    return build(points) + build(points[::-1])[1:-1]

# Area of polygon (Shoelace formula)
def polygon_area(pts):
    n = len(pts)
    area = 0
    for i in range(n):
        j = (i + 1) % n
        area += pts[i][0] * pts[j][1]
        area -= pts[j][0] * pts[i][1]
    return abs(area) / 2

C++ Implementation

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<ll,ll> Point;

ll cross(Point O, Point A, Point B) {
    return (A.first-O.first)*(B.second-O.second) -
           (A.second-O.second)*(B.first-O.first);
}

vector<Point> convexHull(vector<Point> pts) {
    int n = pts.size();
    if (n < 3) return pts;
    sort(pts.begin(), pts.end());
    vector<Point> hull;
    // Lower hull
    for (auto& p : pts) {
        while (hull.size() >= 2 && cross(hull[hull.size()-2], hull.back(), p) <= 0)
            hull.pop_back();
        hull.push_back(p);
    }
    // Upper hull
    int lower_size = hull.size();
    for (int i = n-2; i >= 0; i--) {
        while ((int)hull.size() > lower_size &&
               cross(hull[hull.size()-2], hull.back(), pts[i]) <= 0)
            hull.pop_back();
        hull.push_back(pts[i]);
    }
    hull.pop_back();
    return hull;
}

LeetCode Problems

  • 587. Erect the Fence — convex hull
  • 1232. Check If It Is a Straight Line — cross product check
  • 469. Convex Polygon — all cross products same sign
  • 149. Max Points on a Line — slope normalization with GCD

Advertisement

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro