X-Git-Url: http://www.dolda2000.com/gitweb/?a=blobdiff_plain;f=src%2Fcommon%2Fgeometry.rs;h=455e600040998e685d04fbd1962a81807195fcf9;hb=60058b918569190f437fe996dfc79daf5a431b91;hp=5a03ffb79da30bf2b36007fe0c920bf88989bd18;hpb=1f42d724d84ed1c014ff40ccc91058472391be0c;p=kaka%2Frust-sdl-test.git diff --git a/src/common/geometry.rs b/src/common/geometry.rs index 5a03ffb..455e600 100644 --- a/src/common/geometry.rs +++ b/src/common/geometry.rs @@ -1,5 +1,7 @@ use std::ops::{Add, AddAssign, Sub, SubAssign, Mul, MulAssign, Div, DivAssign, Neg}; +////////// POINT /////////////////////////////////////////////////////////////// + #[macro_export] macro_rules! point { ( $x:expr, $y:expr ) => { @@ -181,6 +183,36 @@ impl Radians { } } +////////// INTERSECTION //////////////////////////////////////////////////////// + +#[derive(Debug)] +pub enum Intersection { + Point(Point), + //Line(Point, Point), // TODO: overlapping collinear + None, +} + +impl Intersection { + pub fn lines(p1: Point, p2: Point, p3: Point, p4: Point) -> Intersection { + let s1 = p2 - p1; + let s2 = p4 - p3; + + let denomimator = -s2.x * s1.y + s1.x * s2.y; + if denomimator != 0.0 { + let s = (-s1.y * (p1.x - p3.x) + s1.x * (p1.y - p3.y)) / denomimator; + let t = ( s2.x * (p1.y - p3.y) - s2.y * (p1.x - p3.x)) / denomimator; + + if s >= 0.0 && s <= 1.0 && t >= 0.0 && t <= 1.0 { + return Intersection::Point(p1 + (s1 * t)) + } + } + + Intersection::None + } +} + +////////// DIMENSION /////////////////////////////////////////////////////////// + #[macro_export] macro_rules! dimen { ( $w:expr, $h:expr ) => { @@ -210,16 +242,7 @@ impl From<(T, T)> for Dimension { } } -#[macro_export] -macro_rules! hashmap { - ($($k:expr => $v:expr),*) => { - { - let mut map = std::collections::HashMap::new(); - $(map.insert($k, $v);)* - map - } - } -} +////////// TESTS /////////////////////////////////////////////////////////////// #[cfg(test)] mod tests { @@ -296,4 +319,18 @@ mod tests { assert_eq!(r.area(), 30 * 20); // let a = Dimension::from(("a".to_string(), "b".to_string())).area(); // this doesn't work, because area() is not implemented for String } + + #[test] + fn intersection_of_lines() { + let p1 = point!(0.0, 0.0); + let p2 = point!(2.0, 2.0); + let p3 = point!(0.0, 2.0); + let p4 = point!(2.0, 0.0); + let r = Intersection::lines(p1, p2, p3, p4); + if let Intersection::Point(p) = r { + assert_eq!(p, point!(1.0, 1.0)); + } else { + panic!(); + } + } }