Expand description
A lightweight library providing a trait for implementing convex hull algorithm on your own datatype.
Feedback welcome!
Found a bug, missing docs, or have a feature request?
Please open an issue on GitHub.
This library offers the ConvexHull trait which provides a divide-and-conquer
convex hull algorithm in O(n log h) [1, 2] via the convex_hull method. The
trait can be implemented easily for any collection type holding point-like types
which fulfills the following conditions:
- The point-like type implements
Into<[f64; 2]>,SyncandClone, - The elements of the collections can be randomly accessed via an
usizeindex, - The elements and their indices can be iterated over.
§Example implementation
Let’s assume we want to implement ConvexHull for a
newtype
wrapper around a slice of [f64; 2]. All we need to do is to tell the trait how
to randomly access the data and how to iterate over the collection:
use planar_convex_hull::{ConvexHull, Index, reinterpret, reinterpret_ref};
struct MySlice<'a>(&'a[[f64; 2]]);
impl<'a> ConvexHull for MySlice<'a> {
/// Index is a newtype of usize and is used to make sure that only indices returned
/// by convex_hull_iter can be used for random data access. It can be converted into
/// usize via the corresponding `From` implementation.
fn convex_hull_get(&self, key: Index) -> [f64; 2] {
// SAFETY: Index is only generated within the convex_hull method out of indices
// returned by convex_hull_iter (which are known to be valid)
return unsafe { self.0.get_unchecked(usize::from(key)) }
.clone()
.into();
}
fn convex_hull_iter(&self) -> impl Iterator<Item = (usize, [f64; 2])> {
return self.0.iter().cloned().map(Into::into).enumerate();
}
}
// Rhombus with two points in its middle
let my_slice = MySlice(&[
[10.0, 4.0],
[-10.0, 4.0],
[0.0, 6.0],
[0.0, 2.0],
[4.0, 4.0], // Not part of the convex hull
[-4.0, 4.0], // Not part of the convex hull
]);
// Returns a `Vec<Index>`. This vector can now be used to access the points via `convex_hull_get`:
let hull = my_slice.convex_hull();
let pts: Vec<[f64; 2]> = hull.iter().map(|i| my_slice.convex_hull_get(*i)).collect();
assert_eq!(pts, vec![[10.0, 4.0], [0.0, 6.0], [-10.0, 4.0], [0.0, 2.0]]);
// Now we want to use the raw usize indices for something else. We can either reinterpret
// a `&'a [Index]` as a `&'a [usize]` ...
let hull_usize_slice = reinterpret_ref(hull.as_slice());
assert_eq!(hull_usize_slice, &[0, 2, 1, 3]);
// ... or convert the `Vec<Index>` into a `Vec<usize>`. Both operations do simply reinterpret
// the bits, since `Index` is defined as a transparent newtype around usize.
let hull_usize_vec = reinterpret(hull);
assert_eq!(hull_usize_vec, vec![0, 2, 1, 3]);§Predefined implementations
The imp module contains implementations of ConvexHull for the following
collection types with P: Into<[f64; 2]>:
Vec<P>HashMap<usize, P>[P; N]withNbeing the size of the array&[P]Slab<P>(only available with feature flagslabenabled)AHashMap<usize, P>(only available with feature flagahashenabled)
Please open an issue on the repository website
https://github.com/StefanMathis/planar_convex_hull if you need an implementation of ConvexHull for additional collection types. You can also
use the newtype
idiom as shown in the example for a reference of a foreign collection instead
(since all methods of ConvexHull operate on shared references).
§Feature flags
All features are disabled by default.
§Parallelizing the divide-and-conquer algorithm
Enabling the rayon feature parallelizes the divide-and-conquer algorithm.
§Implementations for foreign datatypes
The flags slab and ahash provide ConvexHull implementations for
foreign data types. See Predefined implementations.
§Literature
- Liu, Gh., Chen, Cb: A new algorithm for computing the convex hull of a planar point set. J. Zhejiang Univ. - Sci. A 8, 1210–1217 (2007). https://doi.org/10.1631/jzus.2007.A1210
- Saad, Omar: A Convex Hull Algorithm and its implementation in O(n log h) (2017). https://www.codeproject.com/Articles/1210225/Fast-and-improved-D-Convex-Hull-algorithm-and-its
Note: As of June 2026, [2] is unfortunately offline, but can still be reached using the fantastic Wayback machine: https://web.archive.org/web/20250818231303/https://www.codeproject.com/Articles/1210225/Fast-and-improved-D-Convex-Hull-algorithm-and-its A full copy of the website fetched from the Wayback machine is stored in the repo (docs/convex_hull_algorithm.html).
Modules§
- convex_
hull_ impl - This module contains implementations of
ConvexHullfor various foreign types. Some implementations are hidden between feature flags.
Structs§
- Index
- An index known to be valid.
Traits§
- Convex
Hull - A trait for implementing a planar convex hull algorithm for a collection type.
Functions§
- reinterpret
- Reinterprets a
Vec<Index>as aVec<usize>. - reinterpret_
ref - Like
reinterpret, but reinterprets a slice instead of a vector.