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