diff --git a/Cargo.toml b/Cargo.toml index 35f4792..ab191a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,17 +1,20 @@ [package] name = "earcut-rs" -version = "0.3.0" +version = "0.3.1" edition = "2021" +description = "A Rust port of the Earcut polygon triangulation library" authors = ["Taku Fukada ", "MIERUNE Inc. "] -license-file = "LICENSE.txt" +license = "MIT" +repository = "https://github.com/MIERUNE/earcut-rs" +categories = ["graphics", "science"] [dependencies] -num-traits = "0.2.18" +num-traits = "0.2" [dev-dependencies] -serde_json = { version = "1.0.115", features = ["float_roundtrip"] } -serde = { version = "1.0.197", features = ["derive"] } -criterion = "0.5.1" +serde_json = { version = "1.0", features = ["float_roundtrip"] } +serde = { version = "1.0", features = ["derive"] } +criterion = "0.5" [[bench]] name = "benchmark" diff --git a/README.md b/README.md index 6a0d8ee..06d8434 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,13 @@ [![Test](https://github.com/MIERUNE/earcut-rs/actions/workflows/Test.yml/badge.svg)](https://github.com/MIERUNE/earcut-rs/actions/workflows/Test.yml) [![codecov](https://codecov.io/gh/MIERUNE/earcut-rs/graph/badge.svg?token=thKlQiVjLc)](https://codecov.io/gh/MIERUNE/earcut-rs) +[![Crates.io Version](https://img.shields.io/crates/v/earcut-rs)](https://crates.io/crates/earcut-rs) -A Rust port of the [mapbox/earcut](https://github.com/mapbox/earcut) polygon triangulation library, implemented from scratch with reference to [donbright/earcutr](https://github.com/donbright/earcutr). +A Rust port of the [mapbox/earcut](https://github.com/mapbox/earcut) polygon triangulation library, implemented from scratch with some reference to [donbright/earcutr](https://github.com/donbright/earcutr). - Based on the latest earcut 2.2.4 release. -- An additional utility `utils3d` can be used to project polygons from 3D to 2D space before triangulation. +- Designed to avoid unnecessary memory allocations. You can reuse the internal buffer and the output index vector. +- (Experimental) An additional module, `utils3d`, can rotate polygons from 3D to 2D space before triangulation. - License: ISC

diff --git a/src/lib.rs b/src/lib.rs index 8acb6e6..f5c20f8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -105,6 +105,9 @@ impl Default for Earcut { } impl Earcut { + /// Creates a new instance for the earcut algorithm. + /// + /// You can reuse the same instance for multiple triangulations to reduce memory allocations. pub fn new() -> Self { Self { data: Vec::new(), @@ -118,6 +121,9 @@ impl Earcut { self.nodes.reserve(capacity); } + /// Performs the earcut triangulation on a polygon. + /// + /// The API is similar to the original JavaScript implementation, except you can provide a vector for the output indices. pub fn earcut( &mut self, data: impl IntoIterator, @@ -317,7 +323,6 @@ impl Earcut { } /// check whether a polygon node forms a valid ear with adjacent nodes - #[inline] fn is_ear(&self, ear_i: usize) -> bool { let b = node!(self.nodes, ear_i); let a = node!(self.nodes, b.prev_i); @@ -860,7 +865,6 @@ impl Earcut { /// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two; /// if one belongs to the outer ring and another to a hole, it merges it into a single ring - #[inline(always)] fn split_polygon(&mut self, a_i: usize, b_i: usize) -> usize { let a2_i = self.nodes.len(); let b2_i = a2_i + 1; @@ -890,7 +894,6 @@ impl Earcut { } /// create a node and optionally link it with previous one (in a circular doubly linked list) -#[inline(always)] fn insert_node( nodes: &mut Vec>, i: usize, @@ -916,7 +919,6 @@ fn insert_node( p_i } -#[inline(always)] fn remove_node(nodes: &mut [Node], p_i: usize) -> (usize, usize) { let p = node!(nodes, p_i); let p_next_i = p.next_i; @@ -934,7 +936,7 @@ fn remove_node(nodes: &mut [Node], p_i: usize) -> (usize, usize) { (p_prev_i, p_next_i) } -/// return a percentage difference between the polygon area and its triangulation area; +/// Returns a percentage difference between the polygon area and its triangulation area; /// used to verify correctness of triangulation pub fn deviation( data: impl IntoIterator, @@ -1002,7 +1004,6 @@ fn signed_area(data: &[T], start: usize, end: usize) -> T { } /// z-order of a point given coords and inverse of the longer side of data bbox -#[inline(always)] fn z_order(x: T, y: T, min_x: T, min_y: T, inv_size: T) -> u32 { // coords are transformed into non-negative 15-bit integer range let mut x = ((x - min_x) * inv_size).to_u32().unwrap(); @@ -1018,7 +1019,6 @@ fn z_order(x: T, y: T, min_x: T, min_y: T, inv_size: T) -> u32 { x | (y << 1) } -#[inline(always)] #[allow(clippy::too_many_arguments)] fn point_in_triangle(ax: T, ay: T, bx: T, by: T, cx: T, cy: T, px: T, py: T) -> bool { (cx - px) * (ay - py) >= (ax - px) * (cy - py) @@ -1027,24 +1027,20 @@ fn point_in_triangle(ax: T, ay: T, bx: T, by: T, cx: T, cy: T, px: T, } /// signed area of a triangle -#[inline(always)] fn area(p: &Node, q: &Node, r: &Node) -> T { (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y) } /// check if two points are equal -#[inline(always)] fn equals(p1: &Node, p2: &Node) -> bool { p1.x == p2.x && p1.y == p2.y } /// for collinear points p, q, r, check if point q lies on segment pr -#[inline(always)] fn on_segment(p: &Node, q: &Node, r: &Node) -> bool { q.x <= p.x.max(r.x) && q.x >= p.x.min(r.x) && q.y <= p.y.max(r.y) && q.y >= p.y.max(r.y) } -#[inline(always)] fn sign(v: T) -> i8 { (v > T::zero()) as i8 - (v < T::zero()) as i8 }