diff -r 6e0be42d0a8f -r 376a0551b00a rust/integral-geometry/src/lib.rs --- a/rust/integral-geometry/src/lib.rs Sun Nov 04 00:25:27 2018 +0300 +++ b/rust/integral-geometry/src/lib.rs Sun Nov 04 00:20:27 2018 +0100 @@ -1,13 +1,8 @@ extern crate fpnum; use fpnum::distance; -use std::ops::{ - Add, AddAssign, - Div, DivAssign, - Mul, MulAssign, - Sub, SubAssign, - RangeInclusive -}; +use std::cmp::max; +use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, RangeInclusive, Sub, SubAssign}; #[derive(PartialEq, Eq, Clone, Copy, Debug)] pub struct Point { @@ -68,6 +63,26 @@ pub fn cross(self, other: Point) -> i32 { self.dot(other.rotate90()) } + + #[inline] + pub fn fit(&self, rect: &Rect) -> Point { + let x = if self.x > rect.right() { + rect.right() + } else if self.x < rect.left() { + rect.left() + } else { + self.x + }; + let y = if self.y > rect.bottom() { + rect.bottom() + } else if self.y < rect.top() { + rect.top() + } else { + self.y + }; + + Point::new(x, y) + } } #[derive(PartialEq, Eq, Clone, Copy, Debug)] @@ -118,6 +133,11 @@ SizeMask::new(*self) } + #[inline] + pub fn to_square(&self) -> Size { + Size::square(max(self.width, self.height)) + } + pub fn to_grid_index(&self) -> GridIndex { GridIndex::new(*self) } @@ -355,13 +375,13 @@ Rect::from_box(self.left(), point.x, self.top(), point.y), Rect::from_box(point.x, self.right(), self.top(), point.y), Rect::from_box(point.x, self.right(), point.y, self.bottom()), - Rect::from_box(self.left(), point.x, point.y, self.bottom()) + Rect::from_box(self.left(), point.x, point.y, self.bottom()), ] } } pub struct Polygon { - vertices: Vec + vertices: Vec, } impl Polygon { @@ -657,4 +677,12 @@ assert_eq!(r.top_left(), Point::new(10, 0)); assert_eq!(r.with_margin(12), Rect::from_box(22, 88, 12, 58)); } + + #[test] + fn fit() { + let r = Rect::from_box(10, 100, 0, 70); + + assert_eq!(Point::new(0, -10).fit(&r), Point::new(10, 0)); + assert_eq!(Point::new(1000, 1000).fit(&r), Point::new(100, 70)); + } }