Struct cavalier_contours::Polyline[][src]

pub struct Polyline<T = f64> { /* fields omitted */ }

Implementations

impl<T> Polyline<T> where
    T: Real
[src]

pub fn new() -> Self[src]

Create a new empty Polyline with is_closed set to false.

pub fn new_closed() -> Self[src]

Create a new empty Polyline with is_closed set to true.

pub fn with_capacity(capacity: usize) -> Self[src]

Construct a new empty Polyline with is_closed set to false and some reserved capacity.

pub fn len(&self) -> usize[src]

Returns the number of vertexes currently in the polyline.

pub fn is_empty(&self) -> bool[src]

Returns true if self.len() == 0.

pub fn reserve(&mut self, additional: usize)[src]

Reserves capacity for at least additional more elements.

pub fn add(&mut self, x: T, y: T, bulge: T)[src]

Add a vertex to the polyline by giving the x, y, and bulge values of the vertex.

pub fn add_from_array(&mut self, data: [T; 3])[src]

Add vertex from array data (index 0 = x, 1 = y, 2 = bulge).

pub fn next_wrapping_index(&self, i: usize) -> usize[src]

Returns the next wrapping vertex index for the polyline.

If i + 1 >= self.len() then 0 is returned, otherwise i + 1 is returned.

pub fn prev_wrapping_index(&self, i: usize) -> usize[src]

Returns the previous wrapping vertex index for the polyline.

If i == 0 then self.len() - 1 is returned, otherwise i - 1 is returned.

pub fn add_vertex(&mut self, vertex: PlineVertex<T>)[src]

Add a vertex to the polyline by giving a PlineVertex.

pub fn extend_vertexes(&mut self, other: &Polyline<T>)[src]

Copy all vertexes from other to the end of this polyline.

pub fn remove(&mut self, index: usize) -> PlineVertex<T>[src]

Remove vertex at index.

pub fn remove_last(&mut self) -> PlineVertex<T>[src]

Remove last vertex.

pub fn clear(&mut self)[src]

Clear all vertexes.

pub fn is_closed(&self) -> bool[src]

Returns true if the polyline is closed, false if it is open.

pub fn set_is_closed(&mut self, is_closed: bool)[src]

Allows modifying whether the polyline is closed or not.

pub fn last(&self) -> Option<&PlineVertex<T>>[src]

pub fn last_mut(&mut self) -> Option<&mut PlineVertex<T>>[src]

pub fn set_vertex(&mut self, index: usize, x: T, y: T, bulge: T)[src]

Set the vertex data at a given index of the polyline.

pub fn fuzzy_eq_eps(&self, other: &Self, fuzzy_epsilon: T) -> bool[src]

Fuzzy equal comparison with another polyline using fuzzy_epsilon given.

pub fn fuzzy_eq(&self, other: &Self) -> bool[src]

Fuzzy equal comparison with another vertex using T::fuzzy_epsilon().

pub fn invert_direction(&mut self)[src]

Invert/reverse the direction of the polyline in place.

This method works by simply reversing the order of the vertexes, and then shifting (by 1 position) and inverting the sign of all the bulge values. E.g. after reversing the vertex the bulge at index 0 becomes negative bulge at index 1. The end result for a closed polyline is the direction will be changed from clockwise to counter clockwise or vice versa.

pub fn scale(&mut self, scale_factor: T)[src]

Uniformly scale the polyline in the xy plane by scale_factor.

Examples

let mut polyline = Polyline::new();
polyline.add(2.0, 2.0, 0.5);
polyline.add(4.0, 4.0, 1.0);
polyline.scale(2.0);
let mut expected = Polyline::new();
expected.add(4.0, 4.0, 0.5);
expected.add(8.0, 8.0, 1.0);
assert!(polyline.fuzzy_eq(&expected));

pub fn translate(&mut self, x_offset: T, y_offset: T)[src]

Translate the polyline by some x_offset and y_offset.

Examples

let mut polyline = Polyline::new();
polyline.add(2.0, 2.0, 0.5);
polyline.add(4.0, 4.0, 1.0);
polyline.translate(-3.0, 1.0);
let mut expected = Polyline::new();
expected.add(-1.0, 3.0, 0.5);
expected.add(1.0, 5.0, 1.0);
assert!(polyline.fuzzy_eq(&expected));

pub fn extents(&self) -> Option<AABB<T>>[src]

Compute the XY extents of the polyline.

Returns None if polyline is empty. If polyline has only one vertex then min_x = max_x = polyline[0].x and min_y = max_y = polyline[0].y.

Examples

let mut polyline = Polyline::new();
assert_eq!(polyline.extents(), None);
polyline.add(1.0, 1.0, 1.0);
let pt_extents = polyline.extents().unwrap();
assert!(pt_extents.min_x.fuzzy_eq(1.0));
assert!(pt_extents.min_y.fuzzy_eq(1.0));
assert!(pt_extents.max_x.fuzzy_eq(1.0));
assert!(pt_extents.max_y.fuzzy_eq(1.0));

polyline.add(3.0, 1.0, 1.0);
let extents = polyline.extents().unwrap();
assert!(extents.min_x.fuzzy_eq(1.0));
assert!(extents.min_y.fuzzy_eq(0.0));
assert!(extents.max_x.fuzzy_eq(3.0));
assert!(extents.max_y.fuzzy_eq(1.0));

polyline.set_is_closed(true);
let extents = polyline.extents().unwrap();
assert!(extents.min_x.fuzzy_eq(1.0));
assert!(extents.min_y.fuzzy_eq(0.0));
assert!(extents.max_x.fuzzy_eq(3.0));
assert!(extents.max_y.fuzzy_eq(2.0));

pub fn create_approx_spatial_index(&self) -> Option<StaticAABB2DIndex<T>>[src]

Creates a fast approximate spatial index of all the polyline’s segments.

Starting vertex index position is used for key to the segment bounding box in the StaticAABB2DIndex.

Returns None if polyline vertex count is less than 2 or an error occurs in constructing the spatial index.

pub fn visit_segments<F>(&self, visitor: &mut F) where
    F: FnMut(PlineVertex<T>, PlineVertex<T>) -> bool
[src]

Visit all the polyline segments (represented as polyline vertex pairs, starting at indexes (0, 1)) with a function/closure.

This is equivalent to Polyline::iter_segments but uses a visiting function rather than an iterator.

pub fn iter(&self) -> impl Iterator<Item = &PlineVertex<T>> + Clone[src]

Iterate through all the vertexes in the polyline.

pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut PlineVertex<T>>[src]

Iterate through all the vertexes in the polyline as mutable references.

pub fn iter_segments(
    &self
) -> impl Iterator<Item = (PlineVertex<T>, PlineVertex<T>)> + '_
[src]

Iterate through all the polyline segments (represented as polyline vertex pairs, starting at indexes (0, 1)).

This is equivalent to Polyline::visit_segments but returns an iterator rather than accepting a function.

pub fn iter_segment_indexes(&self) -> impl Iterator<Item = (usize, usize)>[src]

Iterate through all the polyline segment vertex positional indexes.

Segments are represented by polyline vertex pairs, for each vertex there is an associated positional index in the polyline, this method iterates through those positional indexes as segment pairs starting at (0, 1).

pub fn parallel_offset(
    &self,
    offset: T,
    spatial_index: Option<&StaticAABB2DIndex<T>>,
    options: Option<PlineOffsetOptions<T>>
) -> Vec<Polyline<T>>
[src]

Compute the parallel offset polylines of the polyline.

offset determines what offset polylines generated, if it is positive then the direction of the offset is to the left of the polyline segment tangent vectors otherwise it is to the right.

spatial_index is a spatial index of all the polyline’s segment bounding boxes. If None is given then it will be computed internally. Polyline::create_approx_spatial_index may be used to create the spatial index, the only restriction is that the spatial index bounding boxes must be at least big enough to contain the segments.

options is a struct that holds parameters for tweaking the behavior of the algorithm, if None is given then PlineOffsetOptions::default()` will be used. See crate::PlineOffsetOptions for specific parameters.

Examples

// using the options struct to inform the algorithm that there may be self intersects
// in the polyline to be offset
let options = PlineOffsetOptions { handle_self_intersects: true, .. Default::default() };
let pline = pline_closed![(0.0, 0.0, 1.0), (1.0, 0.0, 1.0)];
// passing in None for the spatial_index
let offset_plines = pline.parallel_offset(0.2, None, Some(options));
assert_eq!(offset_plines.len(), 1);
let offset_pline = &offset_plines[0];
assert!(offset_pline[0].fuzzy_eq(PlineVertex::new(0.2, 0.0, 1.0)));
assert!(offset_pline[1].fuzzy_eq(PlineVertex::new(0.8, 0.0, 1.0)));

pub fn area(&self) -> T[src]

Compute the closed signed area of the polyline.

If Polyline::is_closed is false (open polyline) then 0.0 is always returned. The area is signed such that if the polyline direction is counter clockwise then the area is positive, otherwise it is negative.

Examples

let mut polyline: Polyline = Polyline::new();
assert!(polyline.area().fuzzy_eq(0.0));
polyline.add(1.0, 1.0, 1.0);
assert!(polyline.area().fuzzy_eq(0.0));

polyline.add(3.0, 1.0, 1.0);
// polyline is still open so area is 0
assert!(polyline.area().fuzzy_eq(0.0));
polyline.set_is_closed(true);
assert!(polyline.area().fuzzy_eq(std::f64::consts::PI));
polyline.invert_direction();
assert!(polyline.area().fuzzy_eq(-std::f64::consts::PI));

pub fn closest_point(&self, point: Vector2<T>) -> Option<ClosestPointResult<T>>[src]

Find the closest segment point on a polyline to a point given.

If the polyline is empty then None is returned.

Examples

let mut polyline: Polyline = Polyline::new();
assert!(matches!(polyline.closest_point(Vector2::zero()), None));
polyline.add(1.0, 1.0, 1.0);
let result = polyline.closest_point(Vector2::new(1.0, 0.0)).unwrap();
assert_eq!(result.seg_start_index, 0);
assert!(result.seg_point.fuzzy_eq(polyline[0].pos()));
assert!(result.distance.fuzzy_eq(1.0));

pub fn path_length(&self) -> T[src]

Returns the total path length of the polyline.

Examples

let mut polyline: Polyline = Polyline::new();
// open polyline half circle
polyline.add(0.0, 0.0, 1.0);
polyline.add(2.0, 0.0, 1.0);
assert!(polyline.path_length().fuzzy_eq(std::f64::consts::PI));
// close into full circle
polyline.set_is_closed(true);
assert!(polyline.path_length().fuzzy_eq(2.0 * std::f64::consts::PI));

pub fn winding_number(&self, point: Vector2<T>) -> i32[src]

Calculate the winding number for a point relative to the polyline.

The winding number calculates the number of turns/windings around a point that the polyline path makes. For a closed polyline without self intersects there are only three possibilities:

  • -1 (winds around point clockwise)
  • 0 (point is outside the polyline)
  • 1 (winds around the point counter clockwise).

This function always returns 0 if polyline Polyline::is_closed is false.

If the point lies directly on top of one of the polyline segments the result is not defined.

Examples

Polyline without self intersects

let mut polyline: Polyline = Polyline::new_closed();
polyline.add(0.0, 0.0, 1.0);
polyline.add(2.0, 0.0, 1.0);
assert_eq!(polyline.winding_number(Vector2::new(1.0, 0.0)), 1);
assert_eq!(polyline.winding_number(Vector2::new(0.0, 2.0)), 0);
polyline.invert_direction();
assert_eq!(polyline.winding_number(Vector2::new(1.0, 0.0)), -1);

Multiple windings with self intersecting polyline

let mut polyline: Polyline = Polyline::new_closed();
polyline.add(0.0, 0.0, 1.0);
polyline.add(2.0, 0.0, 1.0);
polyline.add(0.0, 0.0, 1.0);
polyline.add(4.0, 0.0, 1.0);
assert_eq!(polyline.winding_number(Vector2::new(1.0, 0.0)), 2);
assert_eq!(polyline.winding_number(Vector2::new(-1.0, 0.0)), 0);
polyline.invert_direction();
assert_eq!(polyline.winding_number(Vector2::new(1.0, 0.0)), -2);

pub fn arcs_to_approx_lines(&self, error_distance: T) -> Option<Self>[src]

Returns a new polyline with all arc segments converted to line segments with some error_distance or None if T fails to cast to or from usize.

error_distance is the maximum distance from any line segment to the arc it is approximating. Line segments are circumscribed by the arc (all line end points lie on the arc path).

Trait Implementations

impl<T: Clone> Clone for Polyline<T>[src]

impl<T: Debug> Debug for Polyline<T>[src]

impl<T> Default for Polyline<T> where
    T: Real
[src]

impl<T> Index<usize> for Polyline<T> where
    T: Real
[src]

type Output = PlineVertex<T>

The returned type after indexing.

impl<T> IndexMut<usize> for Polyline<T> where
    T: Real
[src]

Auto Trait Implementations

impl<T> RefUnwindSafe for Polyline<T> where
    T: RefUnwindSafe

impl<T> Send for Polyline<T> where
    T: Send

impl<T> Sync for Polyline<T> where
    T: Sync

impl<T> Unpin for Polyline<T> where
    T: Unpin

impl<T> UnwindSafe for Polyline<T> where
    T: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.