line_clipping/
lib.rs

1#![no_std]
2//! A rust crate to implement several line clipping algorithms. See the
3//! [documentation](https://docs.rs/line_clipping) for more information. The choice of algorithms is
4//! based on the following article which contains a good summary of the options:
5//!
6//! Matthes D, Drakopoulos V. [Line Clipping in 2D: Overview, Techniques and
7//! Algorithms](https://pmc.ncbi.nlm.nih.gov/articles/PMC9605407/). J Imaging. 2022 Oct
8//! 17;8(10):286. doi: 10.3390/jimaging8100286. PMID: 36286380; PMCID: PMC9605407.
9//!
10//! Supports:
11//!
12//! - [x] [Cohen-Sutherland](crate::cohen_sutherland)
13//!
14//! TODO
15//!
16//! - [ ] Cyrus-Beck
17//! - [ ] Liang-Barsky
18//! - [ ] Nicholl-Lee-Nicholl
19//! - [ ] More comprehensive testing
20//!
21//! # Installation
22//!
23//! ```shell
24//! cargo add line-clipping
25//! ```
26//!
27//! # Minimum supported Rust version
28//!
29//! The crate is built with Rust 1.85 to match the 2024 edition. The MSRV may increase in a
30//! future minor release, but will be noted in the changelog.
31//!
32//! # Usage
33//!
34//! ```rust
35//! use line_clipping::cohen_sutherland::clip_line;
36//! use line_clipping::{LineSegment, Point, Window};
37//!
38//! let line = LineSegment::new(Point::new(-10.0, -10.0), Point::new(20.0, 20.0));
39//! let window = Window::new(0.0, 10.0, 0.0, 10.0);
40//! let clipped_line = clip_line(line, window);
41//! ```
42//!
43//! # License
44//!
45//! Copyright (c) Josh McKinney
46//!
47//! This project is licensed under either of
48//!
49//! - MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)
50//! - Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
51//!
52//! at your option.
53//!
54//! # Contribution
55//!
56//! Contributions are welcome! Please open an issue or submit a pull request.
57//!
58//! Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in
59//! the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without
60//! any additional terms or conditions.
61pub mod cohen_sutherland;
62
63/// A point in 2D space.
64#[derive(Debug, Clone, Copy, PartialEq)]
65pub struct Point {
66    /// The x coordinate of the point.
67    pub x: f64,
68
69    /// The y coordinate of the point.
70    pub y: f64,
71}
72
73impl Point {
74    /// A point at the origin (0.0, 0.0).
75    pub const ORIGIN: Self = Self { x: 0.0, y: 0.0 };
76
77    /// Creates a new point.
78    #[must_use]
79    pub const fn new(x: f64, y: f64) -> Self {
80        Self { x, y }
81    }
82}
83
84/// A line segment in 2D space.
85#[derive(Debug, Clone, Copy, PartialEq)]
86pub struct LineSegment {
87    /// The first point of the line segment.
88    pub p1: Point,
89
90    /// The second point of the line segment.
91    pub p2: Point,
92}
93
94impl LineSegment {
95    /// Creates a new line segment.
96    #[must_use]
97    pub const fn new(p1: Point, p2: Point) -> Self {
98        Self { p1, p2 }
99    }
100}
101
102/// A rectangular region to clip lines against.
103#[derive(Debug, Clone, Copy)]
104pub struct Window {
105    /// The minimum x coordinate of the window.
106    pub x_min: f64,
107
108    /// The maximum x coordinate of the window.
109    pub x_max: f64,
110
111    /// The minimum y coordinate of the window.
112    pub y_min: f64,
113
114    /// The maximum y coordinate of the window.
115    pub y_max: f64,
116}
117
118impl Window {
119    /// Creates a new window.
120    #[must_use]
121    pub const fn new(x_min: f64, x_max: f64, y_min: f64, y_max: f64) -> Self {
122        Self {
123            x_min,
124            x_max,
125            y_min,
126            y_max,
127        }
128    }
129}