Trait piet_common::kurbo::Shape [−]
A generic trait for open and closed shapes.
This trait provides conversion from shapes to BezPath
s, as well as
general geometry functionality like computing area
, bounding_box
es,
and winding
number.
Associated Types
type PathElementsIter: Iterator
The iterator returned by the path_elements
method.
Required methods
pub fn path_elements(&self, tolerance: f64) -> Self::PathElementsIter
Returns an iterator over this shape expressed as PathEl
s;
that is, as Bézier path elements.
All shapes can be represented as Béziers, but in many situations
(such as when interfacing with a platform drawing API) there are more
efficient native types for specific concrete shapes. In this case,
the user should exhaust the as_
methods (as_rect
, as_line
, etc)
before converting to a BezPath
, as those are likely to be more
efficient.
In many cases, shapes are able to iterate their elements without
allocating; however creating a a BezPath
object always allocates.
If you need an owned BezPath
you can use to_path
instead.
Tolerance
The tolerance
parameter controls the accuracy of
conversion of geometric primitives to Bézier curves, as
curves such as circles cannot be represented exactly but
only approximated. For drawing as in UI elements, a value
of 0.1 is appropriate, as it is unlikely to be visible to
the eye. For scientific applications, a smaller value
might be appropriate. Note that in general the number of
cubic Bézier segments scales as tolerance ^ (-1/6)
.
TODO: When GAT’s land, the type of this can be changed to
contain a &'a self
reference, which would let us take
iterators from complex shapes without cloning.
pub fn area(&self) -> f64
Signed area.
This method only produces meaningful results with closed shapes.
The convention for positive area is that y increases when x is positive. Thus, it is clockwise when down is increasing y (the usual convention for graphics), and anticlockwise when up is increasing y (the usual convention for math).
pub fn perimeter(&self, accuracy: f64) -> f64
Total length of perimeter.
pub fn winding(&self, pt: Point) -> i32
The winding number of a point.
This method only produces meaningful results with closed shapes.
The sign of the winding number is consistent with that of area
,
meaning it is +1 when the point is inside a positive area shape
and -1 when it is inside a negative area shape. Of course, greater
magnitude values are also possible when the shape is more complex.
pub fn bounding_box(&self) -> Rect
The smallest rectangle that encloses the shape.
Provided methods
pub fn to_path(&self, tolerance: f64) -> BezPath
Convert to a Bézier path.
This always allocates. It is appropriate when both the source shape and the resulting path are to be retained.
If you only need to iterate the elements (such as to convert them to
drawing commands for a given 2D graphics API) you should prefer
path_elements
, which can avoid allocating where possible.
The tolerance
parameter is the same as for path_elements
.
pub fn into_path(self, tolerance: f64) -> BezPath
Convert into a Bézier path.
This allocates in the general case, but is zero-cost if the
shape is already a BezPath
.
The tolerance
parameter is the same as for path_elements()
.
pub fn path_segments(&self, tolerance: f64) -> Segments<Self::PathElementsIter>ⓘ
Returns an iterator over this shape expressed as Bézier path
segments (PathSeg
s).
The allocation behaviour and tolerance
parameter are the
same as for path_elements()
pub fn contains(&self, pt: Point) -> bool
Returns true
if the Point
is inside this shape.
This is only meaningful for closed shapes.
pub fn as_line(&self) -> Option<Line>
If the shape is a line, make it available.
pub fn as_rect(&self) -> Option<Rect>
If the shape is a rectangle, make it available.
pub fn as_rounded_rect(&self) -> Option<RoundedRect>
If the shape is a rounded rectangle, make it available.
pub fn as_circle(&self) -> Option<Circle>
If the shape is a circle, make it available.
pub fn as_path_slice(&self) -> Option<&[PathEl]>
If the shape is stored as a slice of path elements, make that available.
Note: when GAT’s land, a method like path_elements
would be
able to iterate through the slice with no extra allocation,
without making any assumption that storage is contiguous.
Implementations on Foreign Types
impl<'a, T> Shape for &'a T where
T: Shape,
T: Shape,
Blanket implementation so impl Shape
will accept owned or reference.
type PathElementsIter = <T as Shape>::PathElementsIter
pub fn path_elements(
&self,
tolerance: f64
) -> <&'a T as Shape>::PathElementsIter
&self,
tolerance: f64
) -> <&'a T as Shape>::PathElementsIter
pub fn to_path(&self, tolerance: f64) -> BezPath
pub fn path_segments(
&self,
tolerance: f64
) -> Segments<<&'a T as Shape>::PathElementsIter>ⓘ
&self,
tolerance: f64
) -> Segments<<&'a T as Shape>::PathElementsIter>ⓘ
pub fn area(&self) -> f64
pub fn perimeter(&self, accuracy: f64) -> f64
pub fn winding(&self, pt: Point) -> i32
pub fn bounding_box(&self) -> Rect
pub fn as_circle(&self) -> Option<Circle>
pub fn as_line(&self) -> Option<Line>
pub fn as_rect(&self) -> Option<Rect>
pub fn as_rounded_rect(&self) -> Option<RoundedRect>
pub fn as_path_slice(&self) -> Option<&[PathEl]>
impl<'a> Shape for &'a [PathEl]
Implements Shape
for a slice of PathEl
, provided that the first element of the slice is
not a PathEl::ClosePath
. If it is, several of these functions will panic.
If the slice starts with LineTo
, QuadTo
, or CurveTo
, it will be treated as a MoveTo
.
type PathElementsIter = Cloned<Iter<'a, PathEl>>
pub fn path_elements(
&self,
_tolerance: f64
) -> <&'a [PathEl] as Shape>::PathElementsIterⓘ
&self,
_tolerance: f64
) -> <&'a [PathEl] as Shape>::PathElementsIterⓘ
pub fn to_path(&self, _tolerance: f64) -> BezPath
pub fn area(&self) -> f64
Signed area.
pub fn perimeter(&self, accuracy: f64) -> f64
pub fn winding(&self, pt: Point) -> i32
Winding number of point.
pub fn bounding_box(&self) -> Rect
pub fn as_path_slice(&self) -> Option<&[PathEl]>
Implementors
impl Shape for PathSeg
type PathElementsIter = PathSegIter
pub fn path_elements(&self, _tolerance: f64) -> PathSegIterⓘNotable traits for PathSegIter
impl Iterator for PathSegIter type Item = PathEl;
Notable traits for PathSegIter
impl Iterator for PathSegIter type Item = PathEl;
pub fn area(&self) -> f64
The area under the curve.
We could just return 0, but this seems more useful.
pub fn perimeter(&self, accuracy: f64) -> f64
pub fn winding(&self, _pt: Point) -> i32
pub fn bounding_box(&self) -> Rect
pub fn as_line(&self) -> Option<Line>
impl Shape for Arc
type PathElementsIter = Chain<Once<PathEl>, ArcAppendIter>
pub fn path_elements(&self, tolerance: f64) -> <Arc as Shape>::PathElementsIter
pub fn area(&self) -> f64
Note: shape isn’t closed so area is not well defined.
pub fn perimeter(&self, accuracy: f64) -> f64
Note: Finding the perimiter of an ellipse is fairly involved, so for now just approximate by using the bezier curve representation. (See https://en.wikipedia.org/wiki/Ellipse#Circumference)
pub fn winding(&self, pt: Point) -> i32
Note: shape isn’t closed so a point’s winding number is not well defined.
pub fn bounding_box(&self) -> Rect
impl Shape for BezPath
type PathElementsIter = IntoIter<PathEl, Global>
pub fn path_elements(
&self,
_tolerance: f64
) -> <BezPath as Shape>::PathElementsIter
&self,
_tolerance: f64
) -> <BezPath as Shape>::PathElementsIter
pub fn to_path(&self, _tolerance: f64) -> BezPath
pub fn into_path(self, _tolerance: f64) -> BezPath
pub fn area(&self) -> f64
Signed area.
pub fn perimeter(&self, accuracy: f64) -> f64
pub fn winding(&self, pt: Point) -> i32
Winding number of point.
pub fn bounding_box(&self) -> Rect
pub fn as_path_slice(&self) -> Option<&[PathEl]>
impl Shape for Circle
type PathElementsIter = CirclePathIter
pub fn path_elements(&self, tolerance: f64) -> CirclePathIter
pub fn area(&self) -> f64
pub fn perimeter(&self, _accuracy: f64) -> f64
pub fn winding(&self, pt: Point) -> i32
pub fn bounding_box(&self) -> Rect
pub fn as_circle(&self) -> Option<Circle>
impl Shape for CircleSegment
type PathElementsIter = Chain<Chain<Chain<Chain<Once<PathEl>, Once<PathEl>>, ArcAppendIter>, Once<PathEl>>, ArcAppendIter>
pub fn path_elements(
&self,
tolerance: f64
) -> Chain<Chain<Chain<Chain<Once<PathEl>, Once<PathEl>>, ArcAppendIter>, Once<PathEl>>, ArcAppendIter>
&self,
tolerance: f64
) -> Chain<Chain<Chain<Chain<Once<PathEl>, Once<PathEl>>, ArcAppendIter>, Once<PathEl>>, ArcAppendIter>
pub fn area(&self) -> f64
pub fn perimeter(&self, _accuracy: f64) -> f64
pub fn winding(&self, pt: Point) -> i32
pub fn bounding_box(&self) -> Rect
impl Shape for CubicBez
type PathElementsIter = CubicBezIter
pub fn path_elements(&self, _tolerance: f64) -> CubicBezIterⓘNotable traits for CubicBezIter
impl Iterator for CubicBezIter type Item = PathEl;
Notable traits for CubicBezIter
impl Iterator for CubicBezIter type Item = PathEl;
pub fn area(&self) -> f64
pub fn perimeter(&self, accuracy: f64) -> f64
pub fn winding(&self, _pt: Point) -> i32
pub fn bounding_box(&self) -> Rect
impl Shape for Ellipse
type PathElementsIter = Chain<Once<PathEl>, ArcAppendIter>
pub fn path_elements(
&self,
tolerance: f64
) -> <Ellipse as Shape>::PathElementsIter
&self,
tolerance: f64
) -> <Ellipse as Shape>::PathElementsIter
pub fn area(&self) -> f64
pub fn perimeter(&self, accuracy: f64) -> f64
pub fn winding(&self, pt: Point) -> i32
pub fn bounding_box(&self) -> Rect
impl Shape for Line
type PathElementsIter = LinePathIter
pub fn path_elements(&self, _tolerance: f64) -> LinePathIter
pub fn area(&self) -> f64
Returning zero here is consistent with the contract (area is only meaningful for closed shapes), but an argument can be made that the contract should be tightened to include the Green’s theorem contribution.
pub fn perimeter(&self, _accuracy: f64) -> f64
pub fn winding(&self, _pt: Point) -> i32
Same consideration as area
.
pub fn bounding_box(&self) -> Rect
pub fn as_line(&self) -> Option<Line>
impl Shape for QuadBez
type PathElementsIter = QuadBezIter
pub fn path_elements(&self, _tolerance: f64) -> QuadBezIterⓘNotable traits for QuadBezIter
impl Iterator for QuadBezIter type Item = PathEl;
Notable traits for QuadBezIter
impl Iterator for QuadBezIter type Item = PathEl;
pub fn area(&self) -> f64
pub fn perimeter(&self, accuracy: f64) -> f64
pub fn winding(&self, _pt: Point) -> i32
pub fn bounding_box(&self) -> Rect
impl Shape for Rect
type PathElementsIter = RectPathIter
pub fn path_elements(&self, _tolerance: f64) -> RectPathIter
pub fn area(&self) -> f64
pub fn perimeter(&self, _accuracy: f64) -> f64
pub fn winding(&self, pt: Point) -> i32
Note: this function is carefully designed so that if the plane is tiled with rectangles, the winding number will be nonzero for exactly one of them.