[−]Trait druid::piet::kurbo::Shape
A generic trait for open and closed shapes.
Associated Types
type BezPathIter: Iterator
The iterator resulting from to_bez_path
.
Required methods
fn to_bez_path(&self, tolerance: f64) -> Self::BezPathIter
Convert to a Bézier path, as an iterator over path elements.
Callers should exhaust the as_
methods first, as those are
likely to be more efficient; in the general case, this
allocates.
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.
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).
fn perimeter(&self, accuracy: f64) -> f64
Total length of perimeter.
fn winding(&self, pt: Point) -> i32
Winding number of 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.
fn bounding_box(&self) -> Rect
The smallest rectangle that encloses the shape.
Provided methods
fn into_bez_path(self, tolerance: f64) -> BezPath
Convert into a Bézier path.
Currently, this always allocates. It is appropriate when the resulting path is to be retained.
The tolerance
parameter is the same as
to_bez_path()
.
fn as_line(&self) -> Option<Line>
If the shape is a line, make it available.
fn as_rect(&self) -> Option<Rect>
If the shape is a rectangle, make it available.
fn as_rounded_rect(&self) -> Option<RoundedRect>
If the shape is a rounded rectangle, make it available.
fn as_circle(&self) -> Option<Circle>
If the shape is a circle, make it available.
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 to_bez_path
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> 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 BezPathIter = Cloned<Iter<'a, PathEl>>
fn to_bez_path(&self, _tolerance: f64) -> <&'a [PathEl] as Shape>::BezPathIter
fn area(&self) -> f64
Signed area.
fn perimeter(&self, accuracy: f64) -> f64
fn winding(&self, pt: Point) -> i32
Winding number of point.
fn bounding_box(&self) -> Rect
fn as_path_slice(&self) -> Option<&[PathEl]>
impl<'a, T> Shape for &'a T where
T: Shape,
T: Shape,
Blanket implementation so impl Shape
will accept owned or reference.
type BezPathIter = <T as Shape>::BezPathIter
fn to_bez_path(&self, tolerance: f64) -> <&'a T as Shape>::BezPathIter
fn area(&self) -> f64
fn perimeter(&self, accuracy: f64) -> f64
fn winding(&self, pt: Point) -> i32
fn bounding_box(&self) -> Rect
fn as_circle(&self) -> Option<Circle>
fn as_line(&self) -> Option<Line>
fn as_rect(&self) -> Option<Rect>
fn as_rounded_rect(&self) -> Option<RoundedRect>
fn as_path_slice(&self) -> Option<&[PathEl]>
Implementors
impl Shape for Arc
type BezPathIter = Chain<Once<PathEl>, ArcAppendIter>
fn to_bez_path(&self, tolerance: f64) -> <Arc as Shape>::BezPathIter
fn area(&self) -> f64
Note: shape isn't closed so area is not well defined.
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)
fn winding(&self, pt: Point) -> i32
Note: shape isn't closed so a point's winding number is not well defined.
fn bounding_box(&self) -> Rect
impl Shape for BezPath
type BezPathIter = IntoIter<PathEl>
fn to_bez_path(&self, _tolerance: f64) -> <BezPath as Shape>::BezPathIter
fn area(&self) -> f64
Signed area.
fn perimeter(&self, accuracy: f64) -> f64
fn winding(&self, pt: Point) -> i32
Winding number of point.
fn bounding_box(&self) -> Rect
fn as_path_slice(&self) -> Option<&[PathEl]>
impl Shape for Circle
type BezPathIter = CirclePathIter
fn to_bez_path(&self, tolerance: f64) -> CirclePathIter
fn area(&self) -> f64
fn perimeter(&self, _accuracy: f64) -> f64
fn winding(&self, pt: Point) -> i32
fn bounding_box(&self) -> Rect
fn as_circle(&self) -> Option<Circle>
impl Shape for CircleSegment
type BezPathIter = Chain<Chain<Chain<Chain<Once<PathEl>, Once<PathEl>>, ArcAppendIter>, Once<PathEl>>, ArcAppendIter>
fn to_bez_path(
&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>
fn area(&self) -> f64
fn perimeter(&self, _accuracy: f64) -> f64
fn winding(&self, pt: Point) -> i32
fn bounding_box(&self) -> Rect
impl Shape for Ellipse
type BezPathIter = Chain<Once<PathEl>, ArcAppendIter>
fn to_bez_path(&self, tolerance: f64) -> <Ellipse as Shape>::BezPathIter
fn area(&self) -> f64
fn perimeter(&self, accuracy: f64) -> f64
fn winding(&self, pt: Point) -> i32
fn bounding_box(&self) -> Rect
impl Shape for Line
type BezPathIter = LinePathIter
fn to_bez_path(&self, _tolerance: f64) -> LinePathIter
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.
fn perimeter(&self, _accuracy: f64) -> f64
fn winding(&self, _pt: Point) -> i32
Same consideration as area
.
fn bounding_box(&self) -> Rect
fn as_line(&self) -> Option<Line>
impl Shape for RoundedRect
type BezPathIter = RoundedRectPathIter
fn to_bez_path(&self, tolerance: f64) -> RoundedRectPathIter
fn area(&self) -> f64
fn perimeter(&self, _accuracy: f64) -> f64
fn winding(&self, pt: Point) -> i32
fn bounding_box(&self) -> Rect
fn as_rounded_rect(&self) -> Option<RoundedRect>
impl Shape for Rect
type BezPathIter = RectPathIter
fn to_bez_path(&self, _tolerance: f64) -> RectPathIter
fn area(&self) -> f64
fn perimeter(&self, _accuracy: f64) -> f64
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.