diff options
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..c28487f --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,125 @@ +mod dimensions; +mod internal; +mod point; +mod rect; + +pub use internal::Internal; +pub use dimensions::{Dimensions, HasDimensions}; +pub use point::{Point, HasPosition}; +pub use rect::{Rect, HasRect}; + +pub enum Orientation { + Horizontal, + Vertical, +} + +// ----------------------------------------------------------------------------- +// Orphaned code + +impl Point<i32> { + pub fn rotate_around(&self, origin: Self, radians: f64) -> Self { + let sin = radians.sin(); + let cos = radians.cos(); + let x_diff = (self.x - origin.x) as f64; + let y_diff = (self.y - origin.y) as f64; + let x2 = (x_diff * cos) - (y_diff * sin); + let y2 = (x_diff * sin) + (y_diff * cos); + Point::new(x2.round() as i32 + origin.x, y2.round() as i32 + origin.y) + } + + pub fn intersect<R: Into<Rect<i32, u32>>>(&self, rect: R) -> Option<Point<i32>> { + let rect = rect.into(); + let left = self.x - rect.origin.x; + let top = self.y - rect.origin.y; + if left >= 0 && top >= 0 && rect.width() as i32 > left && rect.height() as i32 > top { + Some(Point::new(left, top)) + } else { + None + } + } +} + +#[cfg(test)] +mod tests { + use crate::Point; + + #[rustfmt::skip] + macro_rules! p {($x:expr, $y:expr) => {Point::new($x, $y)};} + + fn rad(d: f64) -> f64 { + d.to_radians() + } + + #[test] + fn quarter_turns_zero_origin() { + let o = p!(0, 0); + assert_eq!(p!(10, 10), p!(10, 10)); + assert_eq!(p!(10, 0).rotate_around(o, rad(0.0)), p!(10, 0)); + assert_eq!(p!(10, 0).rotate_around(o, rad(1.0)), p!(10, 0)); + assert_eq!(p!(10, 0).rotate_around(o, rad(90.0)), p!(0, 10)); + assert_eq!(p!(10, 0).rotate_around(o, rad(180.0)), p!(-10, 0)); + assert_eq!(p!(10, 0).rotate_around(o, rad(270.0)), p!(0, -10)); + assert_eq!(p!(10, 0).rotate_around(o, rad(360.0)), p!(10, 0)); + assert_eq!(p!(10, 0).rotate_around(o, rad(450.0)), p!(0, 10)); + assert_eq!(p!(10, 0).rotate_around(o, rad(-0.0)), p!(10, 0)); + assert_eq!(p!(10, 0).rotate_around(o, rad(-1.0)), p!(10, 0)); + assert_eq!(p!(10, 0).rotate_around(o, rad(-90.0)), p!(0, -10)); + assert_eq!(p!(10, 0).rotate_around(o, rad(-450.0)), p!(0, -10)); + } + + #[test] + fn partial_turns_zero_origin() { + let o = p!(0, 0); + assert_eq!(p!(10, 0).rotate_around(o, rad(30.0)), p!(9, 5)); + assert_eq!(p!(10, 0).rotate_around(o, rad(45.0)), p!(7, 7)); + assert_eq!(p!(10, 0).rotate_around(o, rad(60.0)), p!(5, 9)); + assert_eq!(p!(10, 0).rotate_around(o, rad(120.0)), p!(-5, 9)); + } + + #[test] + fn positive_origin() { + let o = p!(10, 10); + assert_eq!(p!(15, 10).rotate_around(o, rad(0.0)), p!(15, 10)); + assert_eq!(p!(15, 10).rotate_around(o, rad(45.0)), p!(14, 14)); + assert_eq!(p!(15, 10).rotate_around(o, rad(90.0)), p!(10, 15)); + assert_eq!(p!(0, 0).rotate_around(o, rad(0.0)), p!(0, 0)); + assert_eq!(p!(0, 0).rotate_around(o, rad(45.0)), p!(10, -4)); + assert_eq!(p!(0, 0).rotate_around(o, rad(90.0)), p!(20, 0)); + } + + + use crate::Rect; + macro_rules! r { + ($x:expr,$y:expr;$w:expr,$h:expr) => { + Rect::<i32,u32>::new($x,$y,$w,$h) + }; + } + + #[test] + fn intersection() { + // Intersecting two null rects + assert_eq!(r!(0,0;0,0), r!(0,0;0,0).intersect(r!(0,0;0,0))); + // Intersecting two identical rects + assert_eq!(r!(0,0;4,4), r!(0,0;4,4).intersect(r!(0,0;4,4))); + // Intersecting two signed identical rects + assert_eq!(r!(-4,-4;4,4), r!(-4,-4;4,4).intersect(r!(-4,-4;4,4))); + // Intersecting two horizontally-displaced rects + assert_eq!(r!(2,0;2,4), r!(0,0;4,4).intersect(r!(2,0;4,4))); + assert_eq!(r!(2,0;2,4), r!(2,0;4,4).intersect(r!(0,0;4,4))); + // Intersecting two vertically-displaced rects + assert_eq!(r!(0,2;4,2), r!(0,0;4,4).intersect(r!(0,2;4,4))); + assert_eq!(r!(0,2;4,2), r!(0,2;4,4).intersect(r!(0,0;4,4))); + // Intersecting two adjacent rects + assert_eq!(r!(0,0;0,0), r!(0,0;4,4).intersect(r!(0,4;4,4))); + assert_eq!(r!(0,0;0,0), r!(0,0;4,4).intersect(r!(4,0;4,4))); + assert_eq!(r!(0,0;0,0), r!(0,0;4,4).intersect(r!(4,4;4,4))); + // Intersecting two almost-adjacent rects + assert_eq!(r!(0,0;0,0), r!(0,0;4,4).intersect(r!(0,5;4,4))); + assert_eq!(r!(0,0;0,0), r!(0,0;4,4).intersect(r!(5,0;4,4))); + assert_eq!(r!(0,0;0,0), r!(0,0;4,4).intersect(r!(5,5;4,4))); + // Intersecting two distant rects + assert_eq!(r!(0,0;0,0), r!(0,0;4,4).intersect(r!( 0,100;4,4))); + assert_eq!(r!(0,0;0,0), r!(0,0;4,4).intersect(r!(100, 0;4,4))); + assert_eq!(r!(0,0;0,0), r!(0,0;4,4).intersect(r!(100,100;4,4))); + } +} |