A modern C++20 computational geometry library implementing fundamental 2D geometric algorithms with performance optimizations via SIMD (AVX2) support.
- Point: 2D point representation with floating-point coordinates
- Line: Line segment between two points with length calculation
- Contur: Boundary/outline computation for point sets
- File:
ConvexHull.h/cpp - Time Complexity: O(n log n)
- Space Complexity: O(n)
- Description: Computes the convex hull of a point set using the Graham scan algorithm
- Find the point with minimum y-coordinate
- Sort points by polar angle relative to the starting point
- Process points in order, maintaining a stack of hull vertices
- Remove points that create right turns (non-convex angles)
- Advantages: Simple, efficient, handles collinear points well
- File:
Sweep.h/cpp - Time Complexity: O((n + k) log n) where k is the number of intersections
- Space Complexity: O(n)
- Description: Finds all intersection points between line segments
- Features:
- Event-based processing for start/end points and intersections
- Improved sweep status structure using
std::set(O(log n) lookups) instead ofstd::list(O(n) lookups) - Duplicate intersection prevention
- Automatic segment swap on intersection
- File:
PointInPolygon.h/cpp - Time Complexity: O(n) where n is the number of polygon vertices
- Description: Multiple algorithms for point-in-polygon detection
- Fast and efficient for most cases
- Casts a horizontal ray from the point to infinity
- Counts edge crossings
- Variants:
isPointInPolygon(): Returns true if point is inside or on boundaryisPointStrictlyInPolygon(): Returns true only if strictly inside (boundary excluded)
- More robust for complex and concave polygons
- Counts how many times the polygon winds around the point
- Returns winding number (0 if outside, non-zero if inside)
- Better for self-intersecting polygons
- File:
GeometryUtils.h/cpp - Description: Common geometric utility functions
- Function:
polygonArea() - Complexity: O(n)
- Formula: Area = 0.5 * |Σ(x_i * y_{i+1} - x_{i+1} * y_i)|
- Signed Version:
polygonSignedArea()returns negative for clockwise, positive for counter-clockwise
- Function:
polygonPerimeter() - Complexity: O(n)
- Description: Sums the lengths of all edges
- Functions:
closestPointOnSegment(): Returns the point on segment closest to a given pointsquaredDistanceToSegment(): Returns squared distance (faster, avoids sqrt)distanceToSegment(): Returns actual distance
- Complexity: O(1)
- Description: Uses parametric representation and clamping to find projection
- File:
Algorithms2D.h/cpp - Cross Product: Computes 2D cross product for orientation testing
- Half-Plane Test: Determines if a point is LEFT/RIGHT/COLINEAR to a directed line segment
- Single point: O(1)
- Vectorized version: Processes 8 points in parallel using AVX2 (O(1) per 8 points)
- Point-on-Segment: Checks if a point lies on a line segment
- Segment Intersection: Returns intersection point if segments intersect
- Conditional Compilation: Enable with
-DUSE_SIMD=1 - Supported Operations:
- Half-plane test for 8 points simultaneously
- Requires compiler flags:
-mavx2 -O3 -mfma
- Benefits: 8x speedup for batch geometric tests
- Sweep status structure upgraded from
std::list(O(n)) tostd::set(O(log n)) - Reduces Bentley-Ottmann complexity for practical instances
#include "ConvexHull.h"
std::vector<Point> points = {
{2, 4}, {5, 3}, {8, 3}, {9, 2}, {11, 3}
};
std::vector<Point> hull = convexHull(points);
// Returns: {2, 4}, {5, 3}, {9, 2}, {11, 3}#include "PointInPolygon.h"
std::vector<Point> polygon = {
{0, 0}, {4, 0}, {4, 4}, {0, 4}
};
Point test(2, 2);
bool inside = isPointInPolygon(test, polygon); // true
bool strict = isPointStrictlyInPolygon(test, polygon); // true
Point boundary(2, 0);
inside = isPointInPolygon(boundary, polygon); // true
strict = isPointStrictlyInPolygon(boundary, polygon); // false#include "GeometryUtils.h"
std::vector<Point> polygon = {
{0, 0}, {3, 0}, {3, 4}, {0, 4}
};
fbase area = polygonArea(polygon); // 12.0
fbase perimeter = polygonPerimeter(polygon); // 14.0#include "GeometryUtils.h"
Line segment({0, 0}, {4, 0});
Point query(2, 3);
Point closest = closestPointOnSegment(query, segment); // (2, 0)
fbase dist = distanceToSegment(query, segment); // 3.0- C++20 compatible compiler (GCC 10+, Clang 12+, MSVC 2019+)
- CMake 3.15+
- GoogleTest (automatically downloaded via FetchContent)
mkdir build
cd build
cmake ..
cmake --build .cmake -DUSE_SIMD=1 ..
cmake --build ../build/test/UnitTest- Comprehensive unit tests for all algorithms
- Edge case testing:
- Degenerate cases (collinear points, zero-length segments)
- Boundary conditions (points on edges/vertices)
- Duplicate points
- Empty/minimal inputs
- Uses GoogleTest framework for robust test infrastructure
- ✅ Fixed Line::length() bug: Changed subtraction to addition in distance formula
- ✅ Upgraded Convex Hull: Implemented Graham scan algorithm (simpler, more efficient)
- ✅ Added Point-in-Polygon: Implemented both ray-casting and winding number algorithms
- ✅ Added Geometry Utilities: Polygon area, perimeter, closest point calculations
- ✅ Optimized Sweep Status: Replaced O(n) list with O(log n) balanced BST (std::set)
- ✅ Enhanced Testing: Added comprehensive test suites for new algorithms
- ✅ Improved Documentation: Added Doxygen-style comments throughout
AlGeo/
├── src/
│ ├── Core Data Structures
│ │ ├── Point.h/cpp
│ │ ├── Line.h/cpp
│ │ └── Contur.h/cpp
│ ├── Algorithms
│ │ ├── ConvexHull.h/cpp
│ │ ├── Sweep.h/cpp
│ │ ├── PointInPolygon.h/cpp
│ │ ├── GeometryUtils.h/cpp
│ │ └── Algorithms2D.h/cpp
│ ├── Utilities
│ │ ├── Definitions.h
│ │ └── AlGeoCommon.h
│ └── Tests (*_test.cpp)
├── test/
│ ├── CMakeLists.txt
│ └── main.cpp
├── CMakeLists.txt
└── README.md
| Algorithm | Time | Space | Notes |
|---|---|---|---|
| Convex Hull (Graham) | O(n log n) | O(n) | Optimal for general case |
| Sweep Line (Bentley-Ottmann) | O((n+k) log n) | O(n) | k = intersections |
| Point in Polygon | O(n) | O(1) | Works for any polygon |
| Polygon Area (Shoelace) | O(n) | O(1) | Signed area available |
| Closest Point (Segment) | O(1) | O(1) | Constant time projection |
| Half-Plane Test | O(1) | O(1) | Single point |
| Half-Plane Test (Vectorized) | O(1) per 8 | O(8) | With AVX2 |
- Delaunay triangulation
- Voronoi diagram computation
- KD-tree spatial indexing
- Polygon clipping (Sutherland-Hodgman)
- AVX2 optimization for more algorithms
- Graham Scan: R. L. Graham, "An Efficient Algorithm for Determining the Convex Hull of a Finite Planar Set" (1972)
- Bentley-Ottmann: J. L. Bentley & T. A. Ottmann, "Algorithms for Reporting and Counting Geometric Intersections" (1979)
- Ray Casting: Various computational geometry texts
- Shoelace Formula: A. M. Bruckstein & J. L. Poreda (1991)
- Fernuni Hagen Algorithmic Geometry
Last Updated: January 2025 Version: 1.0