pub trait PlineSource {
    type Num: Real;
    type OutputPolyline: PlineCreation<Num = Self::Num>;

Show 37 methods // Required methods fn vertex_count(&self) -> usize; fn is_closed(&self) -> bool; fn get(&self, index: usize) -> Option<PlineVertex<Self::Num>>; fn at(&self, index: usize) -> PlineVertex<Self::Num>; // Provided methods fn iter_segments(&self) -> SegmentIter<'_, Self> { ... } fn iter_vertexes(&self) -> VertexIter<'_, Self> { ... } fn is_empty(&self) -> bool { ... } fn fuzzy_eq_eps<P>(&self, other: &P, eps: Self::Num) -> bool where P: PlineSource<Num = Self::Num> + ?Sized { ... } fn fuzzy_eq<P>(&self, other: &P) -> bool where P: PlineSource<Num = Self::Num> + ?Sized { ... } fn last(&self) -> Option<PlineVertex<Self::Num>> { ... } fn segment_count(&self) -> usize { ... } fn iter_segment_indexes(&self) -> PlineSegIndexIterator { ... } fn next_wrapping_index(&self, i: usize) -> usize { ... } fn prev_wrapping_index(&self, i: usize) -> usize { ... } fn fwd_wrapping_dist(&self, start_index: usize, end_index: usize) -> usize { ... } fn fwd_wrapping_index(&self, start_index: usize, offset: usize) -> usize { ... } fn extents(&self) -> Option<AABB<Self::Num>> { ... } fn path_length(&self) -> Self::Num { ... } fn area(&self) -> Self::Num { ... } fn orientation(&self) -> PlineOrientation { ... } fn remove_repeat_pos( &self, pos_equal_eps: Self::Num ) -> Option<Self::OutputPolyline> { ... } fn remove_redundant( &self, pos_equal_eps: Self::Num ) -> Option<Self::OutputPolyline> { ... } fn rotate_start( &self, start_index: usize, point: Vector2<Self::Num>, pos_equal_eps: Self::Num ) -> Option<Self::OutputPolyline> { ... } fn create_approx_aabb_index(&self) -> StaticAABB2DIndex<Self::Num> { ... } fn create_aabb_index(&self) -> StaticAABB2DIndex<Self::Num> { ... } fn closest_point( &self, point: Vector2<Self::Num>, pos_equal_eps: Self::Num ) -> Option<ClosestPointResult<Self::Num>> { ... } fn winding_number(&self, point: Vector2<Self::Num>) -> i32 { ... } fn arcs_to_approx_lines( &self, error_distance: Self::Num ) -> Option<Self::OutputPolyline> { ... } fn visit_self_intersects<C, V>(&self, visitor: &mut V) -> C where C: ControlFlow, V: PlineIntersectVisitor<Self::Num, C> { ... } fn visit_self_intersects_opt<C, V>( &self, visitor: &mut V, options: &PlineSelfIntersectOptions<'_, Self::Num> ) -> C where C: ControlFlow, V: PlineIntersectVisitor<Self::Num, C> { ... } fn find_intersects<P>( &self, other: &P ) -> PlineIntersectsCollection<Self::Num> where P: PlineSource<Num = Self::Num> + ?Sized { ... } fn find_intersects_opt<P>( &self, other: &P, options: &FindIntersectsOptions<'_, Self::Num> ) -> PlineIntersectsCollection<Self::Num> where P: PlineSource<Num = Self::Num> + ?Sized { ... } fn parallel_offset(&self, offset: Self::Num) -> Vec<Self::OutputPolyline> { ... } fn parallel_offset_opt( &self, offset: Self::Num, options: &PlineOffsetOptions<'_, Self::Num> ) -> Vec<Self::OutputPolyline> { ... } fn boolean<P>( &self, other: &P, operation: BooleanOp ) -> BooleanResult<Self::OutputPolyline> where P: PlineSource<Num = Self::Num> + ?Sized { ... } fn boolean_opt<P>( &self, other: &P, operation: BooleanOp, options: &PlineBooleanOptions<'_, Self::Num> ) -> BooleanResult<Self::OutputPolyline> where P: PlineSource<Num = Self::Num> + ?Sized { ... } fn find_point_at_path_length( &self, target_path_length: Self::Num ) -> Result<(usize, Vector2<Self::Num>), Self::Num> { ... }
}
Expand description

Trait representing a readonly source of polyline data. This trait has all the methods and operations that can be performed on a readonly polyline.

A polyline is a sequence of vertexes and a bool indicating whether the polyline is closed (last vertex forms segment with first vertex) or open (no segment between last and first vertex). For related traits see PlineSourceMut and PlineCreation.

Each vertex has a 2d xy position and bulge value. See PlineVertex for more information.

Required Associated Types§

source

type Num: Real

Numeric type used for the polyline.

source

type OutputPolyline: PlineCreation<Num = Self::Num>

Type used for output when invoking methods that return a new polyline.

Required Methods§

source

fn vertex_count(&self) -> usize

Total number of vertexes.

source

fn is_closed(&self) -> bool

Whether the polyline is closed (true) or open (false).

source

fn get(&self, index: usize) -> Option<PlineVertex<Self::Num>>

Get the vertex at given index position. Returns None if index out of bounds.

source

fn at(&self, index: usize) -> PlineVertex<Self::Num>

Same as PlineSource::get but panics if index is out of bounds.

§Panics

Panics if index is out of bounds.

Provided Methods§

source

fn iter_segments(&self) -> SegmentIter<'_, Self>

Return iterator to iterate over all the polyline segments.

source

fn iter_vertexes(&self) -> VertexIter<'_, Self>

Return iterator to iterate over all the polyline vertexes.

source

fn is_empty(&self) -> bool

Returns true if vertex count is 0.

source

fn fuzzy_eq_eps<P>(&self, other: &P, eps: Self::Num) -> bool
where P: PlineSource<Num = Self::Num> + ?Sized,

Fuzzy compare with another polyline using eps epsilon value for fuzzy comparison of vertexes.

source

fn fuzzy_eq<P>(&self, other: &P) -> bool
where P: PlineSource<Num = Self::Num> + ?Sized,

Same as PlineSource::fuzzy_eq_eps but uses default Self::Num::fuzzy_epsilon().

source

fn last(&self) -> Option<PlineVertex<Self::Num>>

Get the last vertex of the polyline or None if polyline is empty.

source

fn segment_count(&self) -> usize

Total number of segments in the polyline.

source

fn iter_segment_indexes(&self) -> PlineSegIndexIterator

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) and ending at (n-2, n-1) if open polyline or (n-1, 0) if closed polyline where n is the number of vertexes.

source

fn next_wrapping_index(&self, i: usize) -> usize

Returns the next wrapping vertex index for the polyline.

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

source

fn prev_wrapping_index(&self, i: usize) -> usize

Returns the previous wrapping vertex index for the polyline.

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

source

fn fwd_wrapping_dist(&self, start_index: usize, end_index: usize) -> usize

Returns the forward wrapping distance between two vertex indexes.

Assumes start_index is valid, debug asserts start_index < self.len().

§Examples
let mut polyline = Polyline::new_closed();
polyline.add(0.0, 0.0, 0.0);
polyline.add(0.0, 0.0, 0.0);
polyline.add(0.0, 0.0, 0.0);
polyline.add(0.0, 0.0, 0.0);
assert_eq!(polyline.fwd_wrapping_dist(0, 2), 2);
assert_eq!(polyline.fwd_wrapping_dist(3, 1), 2);
source

fn fwd_wrapping_index(&self, start_index: usize, offset: usize) -> usize

Returns the vertex index after applying offset to start_index in a wrapping manner.

Assumes start_index is valid, debug asserts start_index < self.len(). Assumes offset does not wrap multiple times, debug asserts offset <= self.len().

§Examples
let mut polyline = Polyline::new_closed();
polyline.add(0.0, 0.0, 0.0);
polyline.add(0.0, 0.0, 0.0);
polyline.add(0.0, 0.0, 0.0);
polyline.add(0.0, 0.0, 0.0);
assert_eq!(polyline.fwd_wrapping_index(0, 2), 2);
assert_eq!(polyline.fwd_wrapping_index(1, 2), 3);
assert_eq!(polyline.fwd_wrapping_index(1, 3), 0);
assert_eq!(polyline.fwd_wrapping_index(2, 3), 1);
source

fn extents(&self) -> Option<AABB<Self::Num>>

Compute the XY extents of the polyline.

Returns None if polyline has less than 2 vertexes.

§Examples
let mut polyline = Polyline::new();
assert_eq!(polyline.extents(), None);
polyline.add(1.0, 1.0, 1.0);
assert_eq!(polyline.extents(), None);

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));
source

fn path_length(&self) -> Self::Num

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));
source

fn area(&self) -> Self::Num

Compute the closed signed area of the polyline.

If PlineSource::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_mut();
assert!(polyline.area().fuzzy_eq(-std::f64::consts::PI));
source

fn orientation(&self) -> PlineOrientation

Returns the orientation of the polyline.

This method just uses the PlineSource::area function to determine directionality of a closed polyline which may not yield a useful result if the polyline has self intersects.

source

fn remove_repeat_pos( &self, pos_equal_eps: Self::Num ) -> Option<Self::OutputPolyline>

Remove all repeat position vertexes from the polyline.

Returns None to avoid allocation and copy in the case that no vertexes are removed.

§Examples
let mut polyline = Polyline::new_closed();
polyline.add(2.0, 2.0, 0.5);
polyline.add(2.0, 2.0, 1.0);
polyline.add(3.0, 3.0, 1.0);
polyline.add(3.0, 3.0, 0.5);
let result = polyline.remove_repeat_pos(1e-5).expect("repeat position vertexes were removed");
assert_eq!(result.vertex_count(), 2);
assert!(result[0].fuzzy_eq(PlineVertex::new(2.0, 2.0, 1.0)));
assert!(result[1].fuzzy_eq(PlineVertex::new(3.0, 3.0, 0.5)));
source

fn remove_redundant( &self, pos_equal_eps: Self::Num ) -> Option<Self::OutputPolyline>

Remove all redundant vertexes from the polyline.

Redundant vertexes can arise with multiple vertexes on top of each other, along a straight line, or forming a concentric arc with sweep angle less than or equal to PI.

Returns None to avoid allocation and copy in the case that no vertexes are removed.

§Examples
§Removing repeat vertexes along a line
let mut polyline = Polyline::new_closed();
polyline.add(2.0, 2.0, 0.0);
polyline.add(3.0, 3.0, 0.0);
polyline.add(3.0, 3.0, 0.0);
polyline.add(4.0, 4.0, 0.0);
polyline.add(2.0, 4.0, 0.0);
let result = polyline.remove_redundant(1e-5).expect("redundant vertexes were removed");
assert_eq!(result.vertex_count(), 3);
assert!(result.is_closed());
assert!(result[0].fuzzy_eq(PlineVertex::new(2.0, 2.0, 0.0)));
assert!(result[1].fuzzy_eq(PlineVertex::new(4.0, 4.0, 0.0)));
assert!(result[2].fuzzy_eq(PlineVertex::new(2.0, 4.0, 0.0)));
§Simplifying a circle defined by 5 vertexes
let bulge = (std::f64::consts::PI / 8.0).tan();
let mut polyline = Polyline::new_closed();
polyline.add(-0.5, 0.0, bulge);
polyline.add(0.0, -0.5, bulge);
// repeat vertex thrown in
polyline.add(0.0, -0.5, bulge);
polyline.add(0.5, 0.0, bulge);
polyline.add(0.0, 0.5, bulge);
let result = polyline.remove_redundant(1e-5).expect("redundant vertexes were removed");
assert_eq!(result.vertex_count(), 2);
assert!(result.is_closed());
assert!(result[0].fuzzy_eq(PlineVertex::new(-0.5, 0.0, 1.0)));
assert!(result[1].fuzzy_eq(PlineVertex::new(0.5, 0.0, 1.0)));
source

fn rotate_start( &self, start_index: usize, point: Vector2<Self::Num>, pos_equal_eps: Self::Num ) -> Option<Self::OutputPolyline>

Rotates the vertexes in a closed polyline such that the first vertex’s position is at point. start_index indicates which segment point lies on before rotation. This does not change the shape of the polyline curve. pos_equal_eps is epsilon value used for comparing the positions of points. None is returned if the polyline is not closed, the polyline length is less than 2, or the start_index is out of bounds.

§Examples
let mut polyline = Polyline::new_closed();
assert!(matches!(polyline.rotate_start(0, Vector2::new(0.0, 0.0), 1e-5), None));
polyline.add(0.0, 0.0, 0.0);
assert!(matches!(polyline.rotate_start(0, Vector2::new(0.0, 0.0), 1e-5), None));
polyline.add(1.0, 0.0, 0.0);
polyline.add(1.0, 1.0, 0.0);
polyline.add(0.0, 1.0, 0.0);

let rot = polyline.rotate_start(0, Vector2::new(0.5, 0.0), 1e-5).unwrap();
let mut expected_rot = Polyline::new_closed();
expected_rot.add(0.5, 0.0, 0.0);
expected_rot.add(1.0, 0.0, 0.0);
expected_rot.add(1.0, 1.0, 0.0);
expected_rot.add(0.0, 1.0, 0.0);
expected_rot.add(0.0, 0.0, 0.0);
assert!(rot.fuzzy_eq(&expected_rot));
source

fn create_approx_aabb_index(&self) -> StaticAABB2DIndex<Self::Num>

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

The starting vertex index position is used as the key to the segment bounding box in the StaticAABB2DIndex. The bounding boxes are guaranteed to be no smaller than the actual bounding box of the segment but may be larger, this is done for performance. If you want the actual bounding box index use PlineSource::create_aabb_index instead.

§Panics

Panics if Self::Num type fails to cast to/from a u16.

source

fn create_aabb_index(&self) -> StaticAABB2DIndex<Self::Num>

Creates a spatial index of all the polyline segments.

The starting vertex index position is used as the key to the segment bounding box in the StaticAABB2DIndex. The bounding boxes are the actual bounding box of the segment, for performance reasons you may want to use PlineSource::create_approx_aabb_index.

§Panics

Panics if Self::Num type fails to cast to/from a u16.

source

fn closest_point( &self, point: Vector2<Self::Num>, pos_equal_eps: Self::Num ) -> Option<ClosestPointResult<Self::Num>>

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

If the polyline is empty then None is returned.

pos_equal_eps is epsilon value used for fuzzy float comparisons.

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

fn winding_number(&self, point: Vector2<Self::Num>) -> i32

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 (polyline winds around point clockwise)
  • 0 (point is outside the polyline)
  • 1 (polyline winds around the point counter clockwise).

For a self intersecting closed polyline the winding number may be less than -1 (if the polyline winds around the point more than once in the counter clockwise direction) or greater than 1 (if the polyline winds around the point more than once in the clockwise direction).

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

If the point lies directly on top of one of the polyline segments the result is not defined (it may return any integer). To handle the case of the point lying directly on the polyline PlineSource::closest_point may be used to check if the distance from the point to the polyline is zero.

§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_mut();
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_mut();
assert_eq!(polyline.winding_number(Vector2::new(1.0, 0.0)), -2);
source

fn arcs_to_approx_lines( &self, error_distance: Self::Num ) -> Option<Self::OutputPolyline>

Returns a new polyline with all arc segments converted to line segments with some error_distance or None if Self::Num 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).

source

fn visit_self_intersects<C, V>(&self, visitor: &mut V) -> C
where C: ControlFlow, V: PlineIntersectVisitor<Self::Num, C>,

Visit self intersects of the polyline using default options.

§Panics

Panics if Self::Num type fails to cast to/from a u16 (required for spatial index).

source

fn visit_self_intersects_opt<C, V>( &self, visitor: &mut V, options: &PlineSelfIntersectOptions<'_, Self::Num> ) -> C
where C: ControlFlow, V: PlineIntersectVisitor<Self::Num, C>,

Visit self intersects of the polyline using options provided.

§Panics

Panics if Self::Num type fails to cast to/from a u16 (required for spatial index).

source

fn find_intersects<P>(&self, other: &P) -> PlineIntersectsCollection<Self::Num>
where P: PlineSource<Num = Self::Num> + ?Sized,

Find all intersects between two polylines using default options.

§Panics

Panics if Self::Num type fails to cast to/from a u16 (required for spatial index).

source

fn find_intersects_opt<P>( &self, other: &P, options: &FindIntersectsOptions<'_, Self::Num> ) -> PlineIntersectsCollection<Self::Num>
where P: PlineSource<Num = Self::Num> + ?Sized,

Find all intersects between two polylines using the options provided.

§Panics

Panics if Self::Num type fails to cast to/from a u16 (required for spatial index).

source

fn parallel_offset(&self, offset: Self::Num) -> Vec<Self::OutputPolyline>

Compute the parallel offset polylines of the polyline using default options.

offset determines what offset polylines are 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.

Algorithm will use PlineOffsetOptions::default for algorithm options.

§Panics

Panics if Self::Num type fails to cast to/from a u16 (required for spatial index).

§Examples
let pline = pline_closed![(0.0, 0.0, 1.0), (1.0, 0.0, 1.0)];
let offset_plines = pline.parallel_offset(0.2);
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)));
source

fn parallel_offset_opt( &self, offset: Self::Num, options: &PlineOffsetOptions<'_, Self::Num> ) -> Vec<Self::OutputPolyline>

Compute the parallel offset polylines of the polyline with options given.

offset determines what offset polylines are 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.

options is a struct that holds optional parameters. See PlineOffsetOptions for specific parameters.

§Panics

Panics if Self::Num type fails to cast to/from a u16 (required for spatial index).

§Examples
let pline = pline_closed![(0.0, 0.0, 1.0), (1.0, 0.0, 1.0)];
let aabb_index = pline.create_approx_aabb_index();
let options = PlineOffsetOptions {
    // setting option to handle possible self intersects in the polyline
    handle_self_intersects: true,
    // passing in existing spatial index of the polyline segments
    aabb_index: Some(&aabb_index),
    ..Default::default()
};
let offset_plines = pline.parallel_offset_opt(0.2, &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)));
source

fn boolean<P>( &self, other: &P, operation: BooleanOp ) -> BooleanResult<Self::OutputPolyline>
where P: PlineSource<Num = Self::Num> + ?Sized,

Perform a boolean operation between this polyline and another using default options.

See PlineSource::boolean_opt for more information.

§Panics

Panics if Self::Num type fails to cast to/from a u16 (required for spatial index).

§Examples
let rectangle = pline_closed![
    (-1.0, -2.0, 0.0),
    (3.0, -2.0, 0.0),
    (3.0, 2.0, 0.0),
    (-1.0, 2.0, 0.0),
];
let circle = pline_closed![(0.0, 0.0, 1.0), (2.0, 0.0, 1.0)];
let results = rectangle.boolean(&circle, BooleanOp::Not);
// since the circle is inside the rectangle we get back 1 positive polyline and 1 negative
// polyline where the positive polyline is the rectangle and the negative polyline is the
// circle
assert_eq!(results.pos_plines.len(), 1);
assert_eq!(results.neg_plines.len(), 1);
assert!(matches!(results.result_info, BooleanResultInfo::Pline2InsidePline1));
assert!(results.pos_plines[0].pline.area().fuzzy_eq(rectangle.area()));
assert!(results.neg_plines[0].pline.area().fuzzy_eq(circle.area()));
source

fn boolean_opt<P>( &self, other: &P, operation: BooleanOp, options: &PlineBooleanOptions<'_, Self::Num> ) -> BooleanResult<Self::OutputPolyline>
where P: PlineSource<Num = Self::Num> + ?Sized,

Perform a boolean operation between this polyline and another with options provided.

Returns the boolean result polylines and their associated slices that were stitched together end to end to form them. For the result pline1 refers to self, and pline2 refers to other.

§Panics

Panics if Self::Num type fails to cast to/from a u16 (required for spatial index).

§Examples
let rectangle = pline_closed![
    (-1.0, -2.0, 0.0),
    (3.0, -2.0, 0.0),
    (3.0, 2.0, 0.0),
    (-1.0, 2.0, 0.0),
];
let circle = pline_closed![(0.0, 0.0, 1.0), (2.0, 0.0, 1.0)];
let aabb_index = rectangle.create_approx_aabb_index();
let options = PlineBooleanOptions {
    // passing in existing spatial index of the polyline segments for the first polyline
    pline1_aabb_index: Some(&aabb_index),
    ..Default::default()
};
let results = rectangle.boolean_opt(&circle, BooleanOp::Not, &options);
// since the circle is inside the rectangle we get back 1 positive polyline and 1 negative
// polyline where the positive polyline is the rectangle and the negative polyline is the
// circle
assert_eq!(results.pos_plines.len(), 1);
assert_eq!(results.neg_plines.len(), 1);
assert!(matches!(results.result_info, BooleanResultInfo::Pline2InsidePline1));
assert!(results.pos_plines[0].pline.area().fuzzy_eq(rectangle.area()));
assert!(results.neg_plines[0].pline.area().fuzzy_eq(circle.area()));
source

fn find_point_at_path_length( &self, target_path_length: Self::Num ) -> Result<(usize, Vector2<Self::Num>), Self::Num>

Find the segment index and point on the polyline corresponding to the path length given.

Returns Ok((0, first_vertex_position)) if target_path_length is negative.

Returns Ok((seg_index, point)) if target_path_length is less than or equal to the polyline’s total path length. Where seg_index is the index of the segment the point lies on, e.g. if point is on the second segment of the polyline then seg_index = 1.

Returns Err((total_path_length)) if target_path_length is greater than total path length of the polyline.

Object Safety§

This trait is not object safe.

Implementors§

source§

impl<'a, P> PlineSource for PlineView<'a, P>
where P: PlineSource + ?Sized,

source§

impl<T> PlineSource for Polyline<T>
where T: Real,

§

type Num = T

§

type OutputPolyline = Polyline<T>