Skip to content

Commit 241c220

Browse files
committed
References to involved classes in documentation + rename PlanarLineStringCurve
1 parent cc91dd1 commit 241c220

File tree

1 file changed

+52
-50
lines changed

1 file changed

+52
-50
lines changed

src/curves.rs

+52-50
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,86 @@
11
//! This module defines a curve and primitive functions on them
22
//! Most common manipulations are projecting a point on the curve
33
//! and otherway round find the coordinates of a point along the curve
4-
//! For now the implementation is based on a [LineString],
4+
//! For now the implementation is based on a [`LineString`],
55
//! but other implementations could be considered such as splines
66
77
use geo::kernels::RobustKernel;
88
use geo::prelude::*;
99
use geo::{coord, Line, LineString, Point, Rect};
1010
use thiserror::Error;
1111

12-
/// A `Curve` is the fundamental building block for an LRM.
12+
/// A [`Curve`] is the fundamental building block for an LRM.
1313
/// It provides basic primitives to locate/project points on it.
14-
/// A `Curve` can be part of a larger `Curve` (e.g. for optimisation purposes and to have better bounding boxes).
15-
/// The `Curve` can be implemented.
14+
/// A [`Curve`] can be part of a larger [`Curve`] (e.g. for optimisation purposes and to have better bounding boxes).
15+
/// The [`Curve`] can be implemented.
1616
pub trait Curve {
17-
/// Builds a new `Curve` from a [LineString].
17+
/// Builds a new[`Curve`] from a [`LineString`].
1818
/// `max_extent` is the maximum distance that is considered to be “on the curve”.
1919
/// `max_extent` plays a role in the bounding box.
2020
fn new(geom: LineString, max_extent: f64) -> Self;
2121

22-
/// Projects the [Point] to the closest position on the `Curve`.
23-
/// Will fail if the `Curve` is invalid (e.g. no `Point` on it)
24-
/// or if the `Point` is too far away.
25-
/// If the `Curve` is a piece of a larger `Curve` (`start_offset > 0`)
26-
/// then the `distance_along_curve` if from the whole `Curve`, not just the current piece.
22+
/// Projects the [`Point`] to the closest position on the [`Curve`].
23+
/// Will fail if the [`Curve`] is invalid (e.g. no [`Point`] on it)
24+
/// or if the [`Point`] is too far away.
25+
/// If the [`Curve`] is a piece of a larger [`Curve`] (`start_offset > 0`)
26+
/// then the `distance_along_curve` if from the whole [`Curve`], not just the current piece.
2727
fn project(&self, point: Point) -> Result<CurveProjection, CurveError>;
2828

29-
/// Returns the geographical position of a [Point] on the `Curve`.
30-
/// Will return an error if the `CurveProjection` is not on this `Curve`.
29+
/// Returns the geographical position of a [`Point`] on the [`Curve`].
30+
/// Will return an error if the `CurveProjection` is not on this [`Curve`].
3131
fn resolve(&self, projection: CurveProjection) -> Result<Point, CurveError>;
3232

33-
/// Bounding box of the `Curve` with a buffer of `max_extent`.
33+
/// Bounding box of the [`Curve`] with a buffer of `max_extent`.
3434
fn bbox(&self) -> Rect;
3535

36-
/// The length of the `Curve`.
36+
/// The length of the [`Curve`].
3737
fn length(&self) -> f64;
3838

39-
/// Computes the normal at a given offset on the `Curve`.
40-
/// Will return an error if the `Curve` is invalid or the offset is outside of the `Curve`.
39+
/// Computes the normal at a given offset on the [`Curve`].
40+
/// Will return an error if the [`Curve`] is invalid or the offset is outside of the [`Curve`].
4141
/// Points to the positive side (left).
4242
fn get_normal(&self, offset: f64) -> Result<(f64, f64), CurveError>;
4343

44-
/// Returns the [Point] where the `Curve` and the segment intersect.
45-
/// If the segment intersects the `Curve` multiple times, an intersection is chosen randomly.
46-
/// When the segment is colinear with the `Curve` it is ignored.
44+
/// Returns the [`Point`] where the [`Curve`] and the segment intersect.
45+
/// If the segment intersects the [`Curve`] multiple times, an intersection is chosen randomly.
46+
/// When the segment is colinear with the [`Curve`] it is ignored.
4747
fn intersect_segment(&self, segment: Line) -> Option<Point>;
4848

4949
/// Is the geometry valid. Depending on the representation.
5050
/// It must have at least two coordinates.
5151
/// If there are exactly two coordinates, they must be different.
5252
fn is_valid(&self) -> bool;
5353

54-
/// How far from the `Curve` could be considered to be still on the `Curve`.
54+
/// How far from the [`Curve`] could be considered to be still on the [`Curve`].
5555
fn max_extent(&self) -> f64;
5656
}
5757

58-
/// Errors when manipulating the [Curve] objects.
58+
/// Errors when manipulating the [`Curve`]s.
5959
#[derive(Error, Debug, PartialEq)]
6060
pub enum CurveError {
61-
/// The condition of validity might differ depending on the [Curve] implementation.
61+
/// The condition of validity might differ depending on the [`Curve`] implementation.
6262
#[error("the curve geometry is not valid")]
6363
InvalidGeometry,
6464
/// At least one coordinate is non a finite number (`NaN`, `infinite`).
6565
#[error("the coordinates are not finite")]
6666
NotFiniteCoordinates,
67-
/// The considered [Point] is not on the [Curve].
67+
/// The considered [`Point`] is not on the [`Curve`].
6868
#[error("the point is not on the curve")]
6969
NotOnTheCurve,
7070
}
7171

72-
/// Implementation based on [LineString]:
73-
/// the [Curve] is a string of continous [Line].
72+
/// Implementation based on [`LineString`]:
73+
/// the [`Curve`] is a string of continous [`Line`]s.
74+
/// Each [`Line`] made up of 2 [`Coord`]s.
75+
/// This implementation doesn't take in account the ellipsoidal model of the earth.
7476
/// The coordinates are reprensented by `f64`.
75-
/// That means a precison of about 1_000_000th of a mm for a `Curve` that spans around the Earth.
76-
pub struct LineStringCurve {
77-
/// When a [Curve] might be a piece of a longer `Curve`
78-
/// then the `start_offset` allows to know how fare along the longer `Curve` we are.
77+
/// That means a precison of about 1_000_000th of a mm for a [`Curve`] that spans around the Earth.
78+
pub struct PlanarLineStringCurve {
79+
/// When a [`Curve`] might be a piece of a longer [`Curve`]
80+
/// then the `start_offset` allows to know how far along the longer [`Curve`] we are.
7981
pub start_offset: f64,
8082

81-
/// The max distance that is considered of being part of the [Curve].
83+
/// The max distance that is considered of being part of the [`Curve`].
8284
/// It is used to compute the bounding box.
8385
pub max_extent: f64,
8486

@@ -89,8 +91,8 @@ pub struct LineStringCurve {
8991
length: f64,
9092
}
9193

92-
impl LineStringCurve {
93-
/// Splits the [LineString] into smaller [Curve] objects of at most `max_len` length.
94+
impl PlanarLineStringCurve {
95+
/// Splits the [`LineString`] into smaller [`Curve`]s of at most `max_len` length.
9496
/// If the initial geometry is invalid, it returns an empty vector.
9597
pub fn new_fragmented(geom: LineString, max_len: f64, max_extent: f64) -> Vec<Self> {
9698
let n = (geom.euclidean_length() / max_len).ceil() as usize;
@@ -106,7 +108,7 @@ impl LineStringCurve {
106108
}
107109
}
108110

109-
impl Curve for LineStringCurve {
111+
impl Curve for PlanarLineStringCurve {
110112
fn new(geom: LineString, max_extent: f64) -> Self {
111113
let length = geom.euclidean_length();
112114
Self {
@@ -211,8 +213,8 @@ impl Curve for LineStringCurve {
211213
Ok((result.end.x, result.end.y))
212214
}
213215

214-
/// It must have at least two coordinates
215-
/// If there are exactly two coordinates, they must be different
216+
/// It must have at least two [`Coord`]s.
217+
/// If there are exactly two [`Coord`]s, they must be different.
216218
fn is_valid(&self) -> bool {
217219
self.geom.coords_count() >= 2 && (self.geom.coords_count() > 2 || !self.geom.is_closed())
218220
}
@@ -222,16 +224,16 @@ impl Curve for LineStringCurve {
222224
}
223225
}
224226

225-
/// Represents a [Point] in space projected on the [Curve]
227+
/// Represents a [`Point`] in space projected on the [`Curve`].
226228
#[derive(Clone, Copy)]
227229
pub struct CurveProjection {
228-
/// How far from the [Curve] start is located the [Point]
229-
/// If the `Curve` is part of a larger `Curve`, `start_offset` is strictly positive
230+
/// How far from the [`Curve`] start is located the [`Point`]
231+
/// If the [`Curve`] is part of a larger [`Curve`], `start_offset` is strictly positive
230232
/// and the `start_offset` will be considered
231233
pub distance_along_curve: f64,
232-
/// How far is the [Point] from the [Curve] (euclidian distance)
233-
/// It is positive if the `Point` is located on the left of the `Curve`
234-
/// and negative if the `Point` is on the right
234+
/// How far is the [`Point`] from the [`Curve`] (euclidian distance)
235+
/// It is positive if the [`Point`] is located on the left of the [`Curve`]
236+
/// and negative if the [`Point`] is on the right
235237
pub offset: f64,
236238
}
237239

@@ -243,14 +245,14 @@ mod tests {
243245
use geo::point;
244246

245247
#[test]
246-
fn length() {
247-
let c = LineStringCurve::new(line_string![(x: 0., y: 0.), (x: 2., y:0.)], 1.);
248+
fn planar_length() {
249+
let c = PlanarLineStringCurve::new(line_string![(x: 0., y: 0.), (x: 2., y:0.)], 1.);
248250
assert_eq!(2., c.length());
249251
}
250252

251253
#[test]
252254
fn projection() {
253-
let mut c = LineStringCurve::new(line_string![(x: 0., y: 0.), (x: 2., y:0.)], 1.);
255+
let mut c = PlanarLineStringCurve::new(line_string![(x: 0., y: 0.), (x: 2., y:0.)], 1.);
254256

255257
let projected = c.project(point! {x: 1., y: 1.}).unwrap();
256258
assert_eq!(1., projected.distance_along_curve);
@@ -267,7 +269,7 @@ mod tests {
267269

268270
#[test]
269271
fn resolve() {
270-
let mut c = LineStringCurve::new(line_string![(x: 0., y: 0.), (x: 2., y:0.)], 1.);
272+
let mut c = PlanarLineStringCurve::new(line_string![(x: 0., y: 0.), (x: 2., y:0.)], 1.);
271273

272274
let mut projection = CurveProjection {
273275
distance_along_curve: 1.,
@@ -287,7 +289,7 @@ mod tests {
287289

288290
#[test]
289291
fn bbox() {
290-
let c = LineStringCurve::new(line_string![(x: 0., y: 0.), (x: 2., y:0.)], 1.);
292+
let c = PlanarLineStringCurve::new(line_string![(x: 0., y: 0.), (x: 2., y:0.)], 1.);
291293
let bbox = c.bbox();
292294

293295
assert_eq!(bbox.min(), coord! {x: -1., y: -1.});
@@ -297,7 +299,7 @@ mod tests {
297299
#[test]
298300
fn intersect_segment() {
299301
// Right angle
300-
let c = LineStringCurve::new(line_string![(x: 0., y: 0.), (x: 2., y:0.)], 1.);
302+
let c = PlanarLineStringCurve::new(line_string![(x: 0., y: 0.), (x: 2., y:0.)], 1.);
301303
let segment = Line::new(coord! {x: 1., y: 1.}, coord! {x: 1., y: -1.});
302304
let intersection = c.intersect_segment(segment);
303305
assert_eq!(intersection, Some(point! {x: 1., y: 0.}));
@@ -311,7 +313,7 @@ mod tests {
311313
assert!(c.intersect_segment(segment).is_none());
312314

313315
// Multiple intersection
314-
let c = LineStringCurve::new(
316+
let c = PlanarLineStringCurve::new(
315317
line_string![(x: 0., y: 0.), (x: 1., y:2.), (x: 2., y: 0.)],
316318
1.,
317319
);
@@ -322,14 +324,14 @@ mod tests {
322324
#[test]
323325
fn fragmented() {
324326
let c =
325-
LineStringCurve::new_fragmented(line_string![(x: 0., y: 0.), (x: 2., y:0.)], 1., 1.);
327+
PlanarLineStringCurve::new_fragmented(line_string![(x: 0., y: 0.), (x: 2., y:0.)], 1., 1.);
326328
assert_eq!(2, c.len());
327329
assert_eq!(1., c[0].length());
328330
}
329331

330332
#[test]
331333
fn normal() {
332-
let c = LineStringCurve::new(line_string![(x: 0., y: 0.), (x: 2., y:0.)], 1.);
334+
let c = PlanarLineStringCurve::new(line_string![(x: 0., y: 0.), (x: 2., y:0.)], 1.);
333335
let normal = c.get_normal(1.).unwrap();
334336
assert_relative_eq!(normal.0, 0.);
335337
assert_relative_eq!(normal.1, 1.);

0 commit comments

Comments
 (0)