Skip to content

Commit

Permalink
Better distance_2 docs (#136)
Browse files Browse the repository at this point in the history
  • Loading branch information
urschrei authored Sep 27, 2023
1 parent c130fe0 commit 31a8407
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 33 deletions.
1 change: 1 addition & 0 deletions rstar/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

## Changed
- Fixed a stack overflow error in `DrainIterator::next`
- Clarified that the distance measure in `distance_2` is not restricted to euclidean distance

# 0.11.0

Expand Down
8 changes: 7 additions & 1 deletion rstar/src/envelope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,13 @@ pub trait Envelope: Clone + PartialEq + ::core::fmt::Debug {
/// Returns this envelope's area. Must be at least 0.
fn area(&self) -> <Self::Point as Point>::Scalar;

/// Returns the euclidean distance to the envelope's border.
/// Returns the squared distance between the envelope's border and a point.
///
/// # Notes
/// - While euclidean distance will be the correct choice for most use cases, any distance metric
/// fulfilling the [usual axioms](https://en.wikipedia.org/wiki/Metric_space)
/// can be used when implementing this method
/// - Implementers **must** ensure that the distance metric used matches that of [crate::PointDistance::distance_2]
fn distance_2(&self, point: &Self::Point) -> <Self::Point as Point>::Scalar;

/// Returns the squared min-max distance, a concept that helps to find nearest neighbors efficiently.
Expand Down
8 changes: 7 additions & 1 deletion rstar/src/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,13 @@ pub trait RTreeObject {
/// assert!(circle.contains_point(&[1.0, 0.0]));
/// ```
pub trait PointDistance: RTreeObject {
/// Returns the squared euclidean distance between an object to a point.
/// Returns the squared distance between an object and a point.
///
/// # Notes
/// - While euclidean distance will be the correct choice for most use cases, any distance metric
/// fulfilling the [usual axioms](https://en.wikipedia.org/wiki/Metric_space)
/// can be used when implementing this method
/// - Implementers **must** ensure that the distance metric used matches that of [crate::Envelope::distance_2]
fn distance_2(
&self,
point: &<Self::Envelope as Envelope>::Point,
Expand Down
66 changes: 35 additions & 31 deletions rstar/src/rtree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ where
///
/// However, creating an r-tree is time consuming
/// and runs in `O(n * log(n))`. Thus, r-trees are suited best if many queries and only few
/// insertions are made. rstar also supports [bulk loading](RTree::bulk_load),
/// insertions are made. `rstar` also supports [bulk loading](RTree::bulk_load),
/// which cuts down the constant factors when creating an r-tree significantly compared to
/// sequential insertions.
///
Expand All @@ -53,16 +53,13 @@ where
/// on fast insertion operations, the resulting r-trees were often suboptimally structured. Another
/// heuristic, called `R*-tree` (r-star-tree), was proposed to improve the tree structure at the cost of
/// longer insertion operations and is currently the crate's only implemented
/// [insertion strategy].
///
/// ## Further reading
/// For more information refer to the [wikipedia article](https://en.wikipedia.org/wiki/R-tree).
/// [InsertionStrategy].
///
/// # Usage
/// The items inserted into an r-tree must implement the [RTreeObject]
/// trait. To support nearest neighbor queries, implement the [PointDistance]
/// trait. Some useful geometric primitives that implement the above traits can be found in the
/// [crate::primitives]x module. Several primitives in the [`geo-types`](https://docs.rs/geo-types/) crate also
/// [crate::primitives] module. Several primitives in the [`geo-types`](https://docs.rs/geo-types/) crate also
/// implement these traits.
///
/// ## Example
Expand All @@ -89,39 +86,21 @@ where
/// All types implementing the [Point] trait can be used as underlying point type.
/// By default, fixed size arrays can be used as points.
///
/// ## Type Parameters
/// * `T`: The type of objects stored in the r-tree.
/// * `Params`: Compile time parameters that change the r-tree's internal layout. Refer to the
/// [RTreeParams] trait for more information.
///
/// ## Defining methods generic over r-trees
/// If a library defines a method that should be generic over the r-tree type signature, make
/// sure to include both type parameters like this:
/// ```
/// # use rstar::{RTree,RTreeObject, RTreeParams};
/// pub fn generic_rtree_function<T, Params>(tree: &mut RTree<T, Params>)
/// where
/// T: RTreeObject,
/// Params: RTreeParams
/// {
/// // ...
/// }
/// ```
/// Otherwise, any user of `generic_rtree_function` would be forced to use
/// a tree with default parameters.
/// # Associating Data with Geometries
/// Users wishing to store associated data with geometries can use [crate::primitives::GeomWithData].
///
/// # Runtime and Performance
/// The runtime of query operations (e.g. `nearest neighbor` or `contains`) is usually
/// `O(log(n))`, where `n` refers to the number of elements contained in the r-tree.
/// A naive sequential algorithm would take `O(n)` time. However, r-trees incur higher
/// build up times: inserting an element into an r-tree costs `O(log(n))` time.
///
/// ## Bulk loading
/// # Bulk loading
/// In many scenarios, insertion is only carried out once for many points. In this case,
/// [RTree::bulk_load] will be considerably faster. Its total run time
/// is still `O(log(n))`.
/// is still `O(log(n))`. **Note the performance caveat related to the computation of the envelope**.
///
/// ## Element distribution
/// # Element distribution
/// The tree's performance heavily relies on the spatial distribution of its elements.
/// Best performance is achieved if:
/// * No element is inserted more than once
Expand All @@ -131,9 +110,33 @@ where
/// For the edge case that all elements are overlapping (e.g, one and the same element
/// is contained `n` times), the performance of most operations usually degrades to `O(n)`.
///
/// # Type Parameters
/// * `T`: The type of objects stored in the r-tree.
/// * `Params`: Compile time parameters that change the r-tree's internal layout. Refer to the
/// [RTreeParams] trait for more information.
///
/// # Defining methods generic over r-trees
/// If a library defines a method that should be generic over the r-tree type signature, make
/// sure to include both type parameters like this:
/// ```
/// # use rstar::{RTree,RTreeObject, RTreeParams};
/// pub fn generic_rtree_function<T, Params>(tree: &mut RTree<T, Params>)
/// where
/// T: RTreeObject,
/// Params: RTreeParams
/// {
/// // ...
/// }
/// ```
/// Otherwise, any user of `generic_rtree_function` would be forced to use
/// a tree with default parameters.
///
/// # (De)Serialization
/// Enable the `serde` feature for [Serde](https://crates.io/crates/serde) support.
///
/// ## Further reading
/// For more information refer to the [wikipedia article](https://en.wikipedia.org/wiki/R-tree).
///
#[derive(Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
Expand Down Expand Up @@ -209,8 +212,9 @@ where
/// Bulk loading runs in `O(n * log(n))`, where `n` is the number of loaded
/// elements.
///
/// Note that the envelope of each element will be accessed many times,
/// so if that computation is expensive, consider memoizing it using [`CachedEnvelope`][crate::primitives::CachedEnvelope].
/// # Note
/// The envelope of each element will be accessed many times during loading. If that computation
/// is expensive, **consider memoizing it** using [`CachedEnvelope`][crate::primitives::CachedEnvelope].
pub fn bulk_load(elements: Vec<T>) -> Self {
Self::bulk_load_with_params(elements)
}
Expand Down

0 comments on commit 31a8407

Please sign in to comment.