diff --git a/docs/attributes.md b/docs/attributes.md index 9246c18..eda29e8 100644 --- a/docs/attributes.md +++ b/docs/attributes.md @@ -10,7 +10,7 @@ It is possible to store extra attributes with each vertex (besides the xyz-coord Those attributes are stored as a JSON object/dictionary, a key-value pair where the key is a string and the value is one of the following [NumPy data types](https://numpy.org/doc/stable/user/basics.types.html): `numpy.bool_`, `numpy.int64`, `numpy.uint64`, unicode (string), and `numpy.float64`. -To attach extra attributes, you first need to define a *schema*, it a list of the attribute names and their data types. +To attach extra attributes, you first need to define a *schema*, which is a list of the attribute names and their data types. [NumPy data types](https://numpy.org/doc/stable/reference/arrays.dtypes.html#arrays-dtypes) must be used to create the schema. ```python @@ -43,7 +43,7 @@ dt.set_vertex_attributes(vi, classification=2, intensity=111.1) ## Retrieving the extra attributes -It is possible to obtain the attributes attached to a single vertex as a JSON object, eg for the vertex with ID 50: +It is possible to retrieve the attributes attached to a single vertex as a JSON object, eg for the vertex with ID 50: ```python a = dt.get_vertex_attributes(50) diff --git a/docs/comparison.md b/docs/comparison.md index d12d6a9..4071f0a 100644 --- a/docs/comparison.md +++ b/docs/comparison.md @@ -1,4 +1,4 @@ -# Comparison +# Comparison to alternatives The two tables below compare startinpy to a few of its main alternatives: diff --git a/docs/howitworks.md b/docs/howitworks.md index 653efd4..af8e645 100644 --- a/docs/howitworks.md +++ b/docs/howitworks.md @@ -14,7 +14,7 @@ The algorithm is based on flips to transform the triangulation (see [Lawson (197 The deletion of a vertex is also possible. The algorithm implemented is a modification of the one of [Mostafavi, Gold, and Dakowicz (2003)](https://doi.org/10.1016/S0098-3004(03)00017-7). -The ears are also filled by flipping, so it's, in theory, more robust. +The ears are also filled by flipping, so it's in theory more robust. I have also extended the algorithm to allow the deletion of vertices on the boundary of the convex hull. The algorithm is sub-optimal, but, in practice, the number of neighbours of a given vertex in a DT is only 6, so it doesn't really matter. @@ -22,14 +22,14 @@ The algorithm is sub-optimal, but, in practice, the number of neighbours of a gi ## The data structure The data structure of the Rust code is a cheap implementation of the star-based structure defined in [Blandford et al. (2003)](https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.9.6823); cheap because the link of each vertex is stored a simple array and not in an optimised blob like they did. -It results in a pretty fast library (comparison will come at some point), but it uses more space than the optimised one. +It results in a pretty fast library (see [comparison to alternatives](./comparison.md)), but it uses more space than the optimised original data structure. -However, notice that the stars are *not* exposed in startinpy, to keep it a simple and higher-level library. +However, notice that in startinpy the stars are *not* exposed to the user, to keep it a simple and higher-level library. The data structure of startinpy is composed of 2 arrays: 1. an array of **Points**, where each entry is an array of 3 floats (x-coordinate, y-coordinate, z-coordinate) -2. an array of **Triangles**, where each **Triangle** is an array of 3 integers, the values of the indices of the 3 vertices (ordered counter-clockwise) in the array of **Points** ({func}`startinpy.DT.points`, which is 0-based, 0 being the infinite vertex). +2. an array of **Triangles**, where each **Triangle** is an array of 3 integers, the values of the indices of the 3 vertices (ordered counter-clockwise) in the array of **Points** ({func}`startinpy.DT.points`, which is 0-based, 0 being the [infinite vertex](#infinite-vertex-and-triangles)). A **Vertex** is an integer, it is the index in the array of points ({func}`startinpy.DT.points`, which is 0-based). @@ -51,7 +51,7 @@ The CGAL library also does this, and [the internal workings are well explained h The *infinite vertex* is the first vertex in the array of points ({func}`startinpy.DT.points`), and, thus, it has the index of 0 (zero). It has infinite coordinates (`[inf inf inf]`), those are of type [numpy infinity](https://numpy.org/devdocs/reference/constants.html#numpy.inf). -An *infinite triangle* is a triangle having the infinite vertex as one of its vertices; a finite triangle doesn't have the infinite vertex is part of the triangulation of the dataset. +An *infinite triangle* is a triangle having the infinite vertex as one of its vertices; a finite triangle doesn't have the infinite vertex as one of its 3 vertices. In the figure, notice that there are 5 finite triangles (126, 236, 346, 456, 516), but the data structure actually stores 5 extra infinite triangles (102, 150, 540, 304, 203). Those are adjacent to the 5 edges on the boundary of the convex hull of the dataset. @@ -143,6 +143,10 @@ True Finally, you can remove the unused/deleted vertices from the {func}`startinpy.DT.points` array by using {func}`startinpy.DT.collect_garbage`, which will assign a new ID to most vertices, and triangles will be updated too. Notice that now 5 vertices are in the array, and only 2 finite triangles are in the DT. +:::{warning} +The function {func}`startinpy.DT.collect_garbage` should be used with care as it is a very slow operation that requires copying all points/triangles in an array and recomputing the indices. Apply it before exporting the triangulation, not after each delete operation. +::: + ```python t.collect_garbage() print(t.points) diff --git a/docs/index.md b/docs/index.md index 57b3314..898fb3d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -10,12 +10,12 @@ The triangulation is computed in 2D, but the *z*-elevation of the vertices is ke The underlying code is written in [Rust](https://www.rust-lang.org/) (so it's rather fast) and [robust arithmetic](https://crates.io/crates/robust) is used (so it shouldn't crash). -startinpy uses the [startin Rust library](https://github.com/hugoledoux/startin) and adds several utilities and functions, for instance, [NumPy](https://numpy.org/) support for input/output, exporting to several formats, and easy-of-use. +startinpy uses the [startin Rust library](https://github.com/hugoledoux/startin) and adds several utilities and functions, for instance [NumPy](https://numpy.org/) support for input/output, export to several formats, and easy-of-use. :::{admonition} startinpy allows you to: 1. insert points incrementally 2. delete vertices (useful for simplification, interpolation, and other operations) -3. interpolate with several methods: TIN, natural neighbours, IDW, Laplace, etc. +3. interpolate with several methods: TIN, natural neighbours, IDW, Laplace, etc 4. use other useful terrain Python libraries that are also NumPy-based, eg [laspy](https://laspy.readthedocs.io), [rasterio](https://rasterio.readthedocs.io), and [meshio](https://github.com/nschloe/meshio) 5. output the TIN to several formats: OBJ, PLY, GeoJSON, and CityJSON 6. store [extra attributes](./attributes.md) for the vertices (eg the ones from LAS/LAZ)