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