1 | // Copyright 2018 the Kurbo Authors
|
2 | // SPDX-License-Identifier: Apache-2.0 OR MIT
|
3 |
|
4 | //! 2D geometry, with a focus on curves.
|
5 | //!
|
6 | //! The kurbo library contains data structures and algorithms for curves and
|
7 | //! vector paths. It was designed to serve the needs of 2D graphics applications,
|
8 | //! but it is intended to be general enough to be useful for other applications.
|
9 | //!
|
10 | //! Kurbo is designed to be used by [`Piet`], a crate for drawing 2D graphics,
|
11 | //! and is in turn used by [`Druid`], a cross-platform GUI toolkit.
|
12 | //!
|
13 | //! # Examples
|
14 | //!
|
15 | //! Basic UI-style geometry:
|
16 | //! ```
|
17 | //! use kurbo::{Insets, Point, Rect, Size, Vec2};
|
18 | //!
|
19 | //! let pt = Point::new(10.0, 10.0);
|
20 | //! let vector = Vec2::new(5.0, -5.0);
|
21 | //! let pt2 = pt + vector;
|
22 | //! assert_eq!(pt2, Point::new(15.0, 5.0));
|
23 | //!
|
24 | //! let rect = Rect::from_points(pt, pt2);
|
25 | //! assert_eq!(rect, Rect::from_origin_size((10.0, 5.0), (5.0, 5.0)));
|
26 | //!
|
27 | //! let insets = Insets::uniform(1.0);
|
28 | //! let inset_rect = rect - insets;
|
29 | //! assert_eq!(inset_rect.size(), Size::new(3.0, 3.0));
|
30 | //! ```
|
31 | //!
|
32 | //! Finding the closest position on a [`Shape`]'s perimeter to a [`Point`]:
|
33 | //!
|
34 | //! ```
|
35 | //! use kurbo::{Circle, ParamCurve, ParamCurveNearest, Point, Shape};
|
36 | //!
|
37 | //! const DESIRED_ACCURACY: f64 = 0.1;
|
38 | //!
|
39 | //! /// Given a shape and a point, returns the closest position on the shape's
|
40 | //! /// perimeter, or `None` if the shape is malformed.
|
41 | //! fn closest_perimeter_point(shape: impl Shape, pt: Point) -> Option<Point> {
|
42 | //! let mut best: Option<(Point, f64)> = None;
|
43 | //! for segment in shape.path_segments(DESIRED_ACCURACY) {
|
44 | //! let nearest = segment.nearest(pt, DESIRED_ACCURACY);
|
45 | //! if best.map(|(_, best_d)| nearest.distance_sq < best_d).unwrap_or(true) {
|
46 | //! best = Some((segment.eval(nearest.t), nearest.distance_sq))
|
47 | //! }
|
48 | //! }
|
49 | //! best.map(|(point, _)| point)
|
50 | //! }
|
51 | //!
|
52 | //! let circle = Circle::new((5.0, 5.0), 5.0);
|
53 | //! let hit_point = Point::new(5.0, -2.0);
|
54 | //! let expectation = Point::new(5.0, 0.0);
|
55 | //! let hit = closest_perimeter_point(circle, hit_point).unwrap();
|
56 | //! assert!(hit.distance(expectation) <= DESIRED_ACCURACY);
|
57 | //! ```
|
58 | //!
|
59 | //! # Features
|
60 | //!
|
61 | //! This crate either uses the standard library or the [`libm`] crate for
|
62 | //! math functionality. The `std` feature is enabled by default, but can be
|
63 | //! disabled, as long as the `libm` feature is enabled. This is useful for
|
64 | //! `no_std` environments. However, note that the `libm` crate is not as
|
65 | //! efficient as the standard library, and that this crate still uses the
|
66 | //! `alloc` crate regardless.
|
67 | //!
|
68 | //! [`Piet`]: https://docs.rs/piet
|
69 | //! [`Druid`]: https://docs.rs/druid
|
70 | //! [`libm`]: https://docs.rs/libm
|
71 |
|
72 | #![forbid (unsafe_code)]
|
73 | #![deny (missing_docs, clippy::trivially_copy_pass_by_ref)]
|
74 | #![warn (rustdoc::broken_intra_doc_links)]
|
75 | #![allow (
|
76 | clippy::unreadable_literal,
|
77 | clippy::many_single_char_names,
|
78 | clippy::excessive_precision,
|
79 | clippy::bool_to_int_with_if
|
80 | )]
|
81 | #![cfg_attr (all(not(feature = "std" ), not(test)), no_std)]
|
82 |
|
83 | #[cfg (not(any(feature = "std" , feature = "libm" )))]
|
84 | compile_error!("kurbo requires either the `std` or `libm` feature" );
|
85 |
|
86 | extern crate alloc;
|
87 |
|
88 | mod affine;
|
89 | mod arc;
|
90 | mod bezpath;
|
91 | mod circle;
|
92 | pub mod common;
|
93 | mod cubicbez;
|
94 | mod ellipse;
|
95 | mod fit;
|
96 | mod insets;
|
97 | mod line;
|
98 | mod mindist;
|
99 | pub mod offset;
|
100 | mod param_curve;
|
101 | mod point;
|
102 | mod quadbez;
|
103 | mod quadspline;
|
104 | mod rect;
|
105 | mod rounded_rect;
|
106 | mod rounded_rect_radii;
|
107 | mod shape;
|
108 | pub mod simplify;
|
109 | mod size;
|
110 | #[cfg (feature = "std" )]
|
111 | mod svg;
|
112 | mod translate_scale;
|
113 | mod vec2;
|
114 |
|
115 | pub use crate::affine::*;
|
116 | pub use crate::arc::*;
|
117 | pub use crate::bezpath::*;
|
118 | pub use crate::circle::*;
|
119 | pub use crate::cubicbez::*;
|
120 | pub use crate::ellipse::*;
|
121 | pub use crate::fit::*;
|
122 | pub use crate::insets::*;
|
123 | pub use crate::line::*;
|
124 | pub use crate::param_curve::*;
|
125 | pub use crate::point::*;
|
126 | pub use crate::quadbez::*;
|
127 | pub use crate::quadspline::*;
|
128 | pub use crate::rect::*;
|
129 | pub use crate::rounded_rect::*;
|
130 | pub use crate::rounded_rect_radii::*;
|
131 | pub use crate::shape::*;
|
132 | pub use crate::size::*;
|
133 | #[cfg (feature = "std" )]
|
134 | pub use crate::svg::*;
|
135 | pub use crate::translate_scale::*;
|
136 | pub use crate::vec2::*;
|
137 | |