Struct bezier_rs::Subpath

source ·
pub struct Subpath<ManipulatorGroupId: Identifier> {
    pub closed: bool,
    /* private fields */
}
Expand description

Structure used to represent a path composed of Bezier curves.

Fields§

§closed: bool

Implementations§

source§

impl<ManipulatorGroupId: Identifier> Subpath<ManipulatorGroupId>

Functionality relating to core Subpath operations, such as constructors and iter.

source

pub fn new( manipulator_groups: Vec<ManipulatorGroup<ManipulatorGroupId>>, closed: bool ) -> Self

Create a new Subpath using a list of ManipulatorGroups. A Subpath with less than 2 ManipulatorGroups may not be closed.

source

pub fn from_bezier(bezier: &Bezier) -> Self

Create a Subpath consisting of 2 manipulator groups from a Bezier.

source

pub fn from_beziers(beziers: &[Bezier], closed: bool) -> Self

Creates a subpath from a slice of Bezier. When two consecutive Beziers do not share an end and start point, this function resolves the discrepancy by simply taking the start-point of the second Bezier as the anchor of the Manipulator Group.

source

pub fn is_empty(&self) -> bool

Returns true if the Subpath contains no ManipulatorGroup.

source

pub fn len(&self) -> usize

Returns the number of ManipulatorGroups contained within the Subpath.

source

pub fn len_segments(&self) -> usize

Returns the number of segments contained within the Subpath.

source

pub fn get_segment(&self, segment_index: usize) -> Option<Bezier>

Returns a copy of the bezier segment at the given segment index, if this segment exists.

source

pub fn iter(&self) -> SubpathIter<'_, ManipulatorGroupId>

Returns an iterator of the Beziers along the Subpath.

source

pub fn manipulator_groups(&self) -> &[ManipulatorGroup<ManipulatorGroupId>]

Returns a slice of the ManipulatorGroups in the Subpath.

source

pub fn manipulator_groups_mut( &mut self ) -> &mut Vec<ManipulatorGroup<ManipulatorGroupId>>

Returns a mutable reference to the ManipulatorGroups in the Subpath.

source

pub fn anchors(&self) -> Vec<DVec2>

Returns a vector of all the anchors (DVec2) for this Subpath.

source

pub fn is_point(&self) -> bool

Returns if the Subpath is equivalent to a single point.

source

pub fn curve_to_svg(&self, svg: &mut String, attributes: String)

Appends to the svg mutable string with an SVG shape representation of the curve.

source

pub fn subpath_to_svg(&self, svg: &mut String, transform: DAffine2) -> Result

Write the curve argument to the string (the d=“…” part)

source

pub fn handle_lines_to_svg(&self, svg: &mut String, attributes: String)

Appends to the svg mutable string with an SVG shape representation of the handle lines.

source

pub fn anchors_to_svg(&self, svg: &mut String, attributes: String)

Appends to the svg mutable string with an SVG shape representation of the anchors.

source

pub fn handles_to_svg(&self, svg: &mut String, attributes: String)

Appends to the svg mutable string with an SVG shape representation of the handles.

source

pub fn to_svg( &self, svg: &mut String, curve_attributes: String, anchor_attributes: String, handle_attributes: String, handle_line_attributes: String )

Returns an SVG representation of the Subpath. Appends to the svg mutable string with an SVG shape representation that includes the curve, the handle lines, the anchors, and the handles.

source

pub fn from_anchors( anchor_positions: impl IntoIterator<Item = DVec2>, closed: bool ) -> Self

Construct a Subpath from an iter of anchor positions.

source

pub fn new_rect(corner1: DVec2, corner2: DVec2) -> Self

Constructs a rectangle with corner1 and corner2 as the two corners.

source

pub fn new_ellipse(corner1: DVec2, corner2: DVec2) -> Self

Constructs an ellipse with corner1 and corner2 as the two corners of the bounding box.

source

pub fn new_regular_polygon(center: DVec2, sides: u64, radius: f64) -> Self

Constructs a regular polygon (ngon). Based on sides and radius, which is the distance from the center to any vertex.

source

pub fn new_star_polygon( center: DVec2, sides: u64, radius: f64, inner_radius: f64 ) -> Self

Constructs a star polygon (n-star). See [new_regular_polygon], but with interspersed vertices at an inner_radius.

source

pub fn new_line(p1: DVec2, p2: DVec2) -> Self

Constructs a line from p1 to p2

source

pub fn new_cubic_spline(points: Vec<DVec2>) -> Self

Construct a cubic spline from a list of points. Based on https://mathworld.wolfram.com/CubicSpline.html.

source§

impl<ManipulatorGroupId: Identifier> Subpath<ManipulatorGroupId>

Functionality relating to looking up properties of the Subpath or points along the Subpath.

source

pub fn compute_lookup_table( &self, steps: Option<usize>, tvalue_type: Option<TValueType> ) -> Vec<DVec2>

Return a selection of equidistant points on the bezier curve. If no value is provided for steps, then the function will default steps to be 10.

source

pub fn length(&self, num_subdivisions: Option<usize>) -> f64

Return the sum of the approximation of the length of each Bezier curve along the Subpath.

  • num_subdivisions - Number of subdivisions used to approximate the curve. The default value is 1000.
source

pub fn global_euclidean_to_local_euclidean( &self, global_t: f64, lengths: &[f64], total_length: f64 ) -> (usize, f64)

Converts from a subpath (composed of multiple segments) to a point along a certain segment represented. The returned tuple represents the segment index and the t value along that segment. Both the input global t value and the output t value are in euclidean space, meaning there is a constant rate of change along the arc length.

source

pub fn project( &self, point: DVec2, options: Option<ProjectionOptions> ) -> Option<(usize, f64)>

Returns the segment index and t value that corresponds to the closest point on the curve to the provided point. Uses a searching algorithm akin to binary search that can be customized using the ProjectionOptions structure.

source§

impl<ManipulatorGroupId: Identifier> Subpath<ManipulatorGroupId>

source

pub fn closed(&self) -> bool

Get whether the subpath is closed.

source

pub fn set_closed(&mut self, new_closed: bool)

Set whether the subpath is closed.

source

pub fn manipulator_from_id( &self, id: ManipulatorGroupId ) -> Option<&ManipulatorGroup<ManipulatorGroupId>>

Access a ManipulatorGroup from a ManipulatorGroupId.

source

pub fn manipulator_mut_from_id( &mut self, id: ManipulatorGroupId ) -> Option<&mut ManipulatorGroup<ManipulatorGroupId>>

Access a mutable ManipulatorGroup from a ManipulatorGroupId.

source

pub fn manipulator_index_from_id(&self, id: ManipulatorGroupId) -> Option<usize>

Access the index of a ManipulatorGroup from a ManipulatorGroupId.

source

pub fn insert_manipulator_group( &mut self, index: usize, group: ManipulatorGroup<ManipulatorGroupId> )

Insert a manipulator group at an index.

source

pub fn push_manipulator_group( &mut self, group: ManipulatorGroup<ManipulatorGroupId> )

Push a manipulator group to the end.

source

pub fn last_manipulator_group_mut( &mut self ) -> Option<&mut ManipulatorGroup<ManipulatorGroupId>>

Get a mutable reference to the last manipulator

source

pub fn remove_manipulator_group( &mut self, index: usize ) -> ManipulatorGroup<ManipulatorGroupId>

Remove a manipulator group at an index.

source

pub fn insert(&mut self, t: SubpathTValue)

Inserts a ManipulatorGroup at a certain point along the subpath based on the parametric t-value provided. Expects t to be within the inclusive range [0, 1].

source

pub fn append_bezier(&mut self, bezier: &Bezier, append_type: AppendType)

Append a Bezier to the end of a subpath from a vector of Bezier. The append_type parameter determines how the function behaves when the subpath’s last anchor is not equal to the Bezier’s start point.

  • IgnoreStart: drops the bezier’s start point in favor of the subpath’s last anchor
  • SmoothJoin(f64): joins the subpath’s endpoint with the bezier’s start with a another Bezier segment that is continuous up to the second derivative if the difference between the subpath’s end point and Bezier’s start point exceeds the wrapped integer value. This function assumes that the position of the Bezier’s starting point is equal to that of the Subpath’s last manipulator group.
source§

impl<ManipulatorGroupId: Identifier> Subpath<ManipulatorGroupId>

source

pub fn evaluate(&self, t: SubpathTValue) -> DVec2

Calculate the point on the subpath based on the parametric t-value provided. Expects t to be within the inclusive range [0, 1].

source

pub fn intersections( &self, other: &Bezier, error: Option<f64>, minimum_separation: Option<f64> ) -> Vec<(usize, f64)>

Calculates the intersection points the subpath has with a given curve and returns a list of (usize, f64) tuples, where the usize represents the index of the curve in the subpath, and the f64 represents the t-value local to that curve where the intersection occurred. Expects the following:

  • other: a Bezier curve to check intersections against
  • error: an optional f64 value to provide an error bound
  • minimum_separation: the minimum difference two adjacent t-values must have when comparing adjacent t-values in sorted order. If the comparison condition is not satisfied, the function takes the larger t-value of the two.
source

pub fn subpath_intersections( &self, other: &Subpath<ManipulatorGroupId>, error: Option<f64>, minimum_separation: Option<f64> ) -> Vec<(usize, f64)>

Calculates the intersection points the subpath has with another given subpath and returns a list of global parametric t-values. This function expects the following:

  • other: a Bezier curve to check intersections against
  • error: an optional f64 value to provide an error bound
source

pub fn ray_test_crossings_count( &self, ray_start: DVec2, ray_direction: DVec2 ) -> usize

Returns how many times a given ray intersects with this subpath. (ray_direction does not need to be normalized.) If this needs to be called frequently with a ray of the same rotation angle, consider instead using [ray_test_crossings_count_prerotated].

source

pub fn ray_test_crossings_count_prerotated( &self, ray_start: DVec2, rotation_matrix: DMat2, rotated_subpath: &Self ) -> usize

Returns how many times a given ray intersects with this subpath. (ray_direction does not need to be normalized.) This version of the function is for better performance when calling it frequently without needing to change the rotation between each call. If that isn’t important, use [ray_test_crossings_count] which provides an easier interface by taking a ray direction vector. Instead, this version requires a rotation matrix for the ray’s rotation and a prerotated version of this subpath that has had its rotation applied.

source

pub fn point_inside(&self, point: DVec2) -> bool

Returns true if the given point is inside this subpath. Open paths are NOT automatically closed so you’ll need to call set_closed(true) before calling this. Self-intersecting subpaths use the evenodd fill rule for checking in/outside-ness: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill-rule. If this needs to be called frequently, consider instead using [point_inside_prerotated] and moving this function’s setup code into your own logic before the repeated call.

source

pub fn point_inside_prerotated( &self, point: DVec2, rotation_matrix1: DMat2, rotation_matrix2: DMat2, rotated_subpath1: &Self, rotated_subpath2: &Self ) -> bool

Returns true if the given point is inside this subpath. Open paths are NOT automatically closed so you’ll need to call set_closed(true) before calling this. Self-intersecting subpaths use the evenodd fill rule for checking in/outside-ness: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill-rule. This version of the function is for better performance when calling it frequently because it lets the caller precompute the rotations once instead of every call. If that isn’t important, use [point_inside] which provides an easier interface. Instead, this version requires a pair of rotation matrices for the ray’s rotation and a pair of prerotated versions of this subpath. They should face in different directions that are unlikely to align in the real world. Consider using the following rotations:

const SIN_13DEG: f64 = 0.22495105434;
const COS_13DEG: f64 = 0.97437006478;
const DIRECTION1: DVec2 = DVec2::new(SIN_13DEG, COS_13DEG);
const DIRECTION2: DVec2 = DVec2::new(-COS_13DEG, -SIN_13DEG);
source

pub fn self_intersections( &self, error: Option<f64>, minimum_separation: Option<f64> ) -> Vec<(usize, f64)>

Returns a list of t values that correspond to the self intersection points of the subpath. For each intersection point, the returned t value is the smaller of the two that correspond to the point.

  • error - For intersections with non-linear beziers, error defines the threshold for bounding boxes to be considered an intersection point.
  • minimum_separation: the minimum difference two adjacent t-values must have when comparing adjacent t-values in sorted order. If the comparison condition is not satisfied, the function takes the larger t-value of the two

NOTE: if an intersection were to occur within an error distance away from an anchor point, the algorithm will filter that intersection out.

source

pub fn rectangle_intersections( &self, corner1: DVec2, corner2: DVec2, error: Option<f64>, minimum_separation: Option<f64> ) -> Vec<(usize, f64)>

Calculates the intersection points the subpath has with a given rectangle and returns a list of (usize, f64) tuples, where the usize represents the index of the curve in the subpath, and the f64 represents the t-value local to that curve where the intersection occurred. Expects the following:

  • corner1: any corner of the axis-aligned box to intersect with
  • corner2: the corner opposite to corner1
  • error: an optional f64 value to provide an error bound
  • minimum_separation: the minimum difference two adjacent t-values must have when comparing adjacent t-values in sorted order. If the comparison condition is not satisfied, the function takes the larger t-value of the two.
source

pub fn rectangle_intersections_exist( &self, corner1: DVec2, corner2: DVec2 ) -> bool

Checks if any intersections exist between this subpath and the four edges of the rectangle defined by the top-left corner1 and bottom-right corner2. This is faster than calling [rectangle_intersections].len() because it short-circuits as soon as an intersection is found.

source

pub fn tangent(&self, t: SubpathTValue) -> DVec2

Returns a normalized unit vector representing the tangent on the subpath based on the parametric t-value provided.

source

pub fn normal(&self, t: SubpathTValue) -> DVec2

Returns a normalized unit vector representing the direction of the normal on the subpath based on the parametric t-value provided.

source

pub fn local_extrema(&self) -> [Vec<f64>; 2]

Returns two lists of t-values representing the local extrema of the x and y parametric subpaths respectively. The list of t-values returned are filtered such that they fall within the range [0, 1].

source

pub fn bounding_box(&self) -> Option<[DVec2; 2]>

Return the min and max corners that represent the bounding box of the subpath.

source

pub fn bounding_box_with_transform( &self, transform: DAffine2 ) -> Option<[DVec2; 2]>

Return the min and max corners that represent the bounding box of the subpath, after a given affine transform.

source

pub fn inflections(&self) -> Vec<f64>

Returns list of t-values representing the inflection points of the subpath. The list of t-values returned are filtered such that they fall within the range [0, 1].

source

pub fn contains_point(&self, target_point: DVec2) -> bool

Does a path contain a point? Based on the non zero winding

source

pub fn poisson_disk_points( &self, separation_disk_diameter: f64, rng: impl FnMut() -> f64 ) -> Vec<DVec2>

Randomly places points across the filled surface of this subpath (which is assumed to be closed). The separation_disk_diameter determines the minimum distance between all points from one another. Conceptually, this works by “throwing a dart” at the subpath’s bounding box and keeping the dart only if:

  • It’s inside the shape
  • It’s not closer than separation_disk_diameter to any other point from a previous accepted dart throw This repeats until accepted darts fill all possible areas between one another.

While the conceptual process described above asymptotically slows down and is never guaranteed to produce a maximal set in finite time, this is implemented with an algorithm that produces a maximal set in O(n) time. The slowest part is actually checking if points are inside the subpath shape.

source

pub fn curvature(&self, t: SubpathTValue) -> f64

Returns the curvature, a scalar value for the derivative at the point t along the subpath. Curvature is 1 over the radius of a circle with an equivalent derivative.

source§

impl<ManipulatorGroupId: Identifier> Subpath<ManipulatorGroupId>

Functionality that transforms Subpaths, such as split, reduce, offset, etc.

source

pub fn split( &self, t: SubpathTValue ) -> (Subpath<ManipulatorGroupId>, Option<Subpath<ManipulatorGroupId>>)

Returns either one or two Subpaths that result from splitting the original Subpath at the point corresponding to t. If the original Subpath was closed, a single open Subpath will be returned. If the original Subpath was open, two open Subpaths will be returned.

source

pub fn reverse(&self) -> Subpath<ManipulatorGroupId>

Returns a Subpath with a reversed winding order. Note that a reversed closed subpath will start on the same manipulator group and simply wind the other direction

source

pub fn trim( &self, t1: SubpathTValue, t2: SubpathTValue ) -> Subpath<ManipulatorGroupId>

Returns an open Subpath that results from trimming the original Subpath between the points corresponding to t1 and t2, maintaining the winding order of the original. If the original Subpath is closed, the order of arguments does matter. The resulting Subpath will wind from the given t1 to t2. That means, if the value of t1 > t2, it will cross the break between endpoints from t1 to t = 1 = 0 to t2. If a path winding in the reverse direction is desired, call trim on the Subpath returned from Subpath::reverse.

source

pub fn apply_transform(&mut self, affine_transform: DAffine2)

Apply a transformation to all of the ManipulatorGroups in the Subpath.

source

pub fn rotate(&self, angle: f64) -> Subpath<ManipulatorGroupId>

Returns a subpath that results from rotating this subpath around the origin by the given angle (in radians).

source

pub fn rotate_about_point( &self, angle: f64, pivot: DVec2 ) -> Subpath<ManipulatorGroupId>

Returns a subpath that results from rotating this subpath around the provided point by the given angle (in radians).

source

pub fn offset(&self, distance: f64, join: Join) -> Subpath<ManipulatorGroupId>

Reduces the segments of the subpath into simple subcurves, then scales each subcurve a set distance away. The intersections of segments of the subpath are joined using the method specified by the join argument.

source

pub fn outline( &self, distance: f64, join: Join, cap: Cap ) -> (Subpath<ManipulatorGroupId>, Option<Subpath<ManipulatorGroupId>>)

Outline returns a single closed subpath (if the original subpath was open) or two closed subpaths (if the original subpath was closed) that forms an approximate outline around the subpath at a specified distance from the curve. Outline takes the following parameters:

  • distance - The outline’s distance from the curve.
  • join - The join type used to cap the endpoints of open bezier curves, and join successive subpath segments.

Trait Implementations§

source§

impl<ManipulatorGroupId: Clone + Identifier> Clone for Subpath<ManipulatorGroupId>

source§

fn clone(&self) -> Subpath<ManipulatorGroupId>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<ManipulatorGroupId: Identifier> Debug for Subpath<ManipulatorGroupId>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<ManipulatorGroupId: Hash + Identifier> Hash for Subpath<ManipulatorGroupId>

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<ManipulatorGroupId: Identifier> Index<usize> for Subpath<ManipulatorGroupId>

§

type Output = ManipulatorGroup<ManipulatorGroupId>

The returned type after indexing.
source§

fn index(&self, index: usize) -> &Self::Output

Performs the indexing (container[index]) operation. Read more
source§

impl<ManipulatorGroupId: Identifier> IndexMut<usize> for Subpath<ManipulatorGroupId>

source§

fn index_mut(&mut self, index: usize) -> &mut Self::Output

Performs the mutable indexing (container[index]) operation. Read more
source§

impl<ManipulatorGroupId: PartialEq + Identifier> PartialEq for Subpath<ManipulatorGroupId>

source§

fn eq(&self, other: &Subpath<ManipulatorGroupId>) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<ManipulatorGroupId: Identifier> StructuralPartialEq for Subpath<ManipulatorGroupId>

Auto Trait Implementations§

§

impl<ManipulatorGroupId> RefUnwindSafe for Subpath<ManipulatorGroupId>
where ManipulatorGroupId: RefUnwindSafe,

§

impl<ManipulatorGroupId> Send for Subpath<ManipulatorGroupId>
where ManipulatorGroupId: Send,

§

impl<ManipulatorGroupId> Sync for Subpath<ManipulatorGroupId>
where ManipulatorGroupId: Sync,

§

impl<ManipulatorGroupId> Unpin for Subpath<ManipulatorGroupId>
where ManipulatorGroupId: Unpin,

§

impl<ManipulatorGroupId> UnwindSafe for Subpath<ManipulatorGroupId>
where ManipulatorGroupId: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.