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
use core::ops::{Add, Div, Mul, Sub}; use num_traits::Signed; #[inline] pub fn intersect<T>(s1: &[T; 2], s2: &[T; 2], c1: &[T; 2], c2: &[T; 2]) -> Option<([T; 2], T, T)> where T: Signed + PartialEq + PartialOrd, for<'a, 'b> &'a T: Div<&'b T, Output = T> + Sub<&'b T, Output = T> + Add<&'b T, Output = T> + Mul<&'b T, Output = T>, { let den = &(&c2[1] - &c1[1]) * &(&s2[0] - &s1[0]) - &(&c2[0] - &c1[0]) * &(&s2[1] - &s1[1]); if &den == &T::zero() { None } else { let us = &(&(&c2[0] - &c1[0]) * &(&s1[1] - &c1[1]) - &(&c2[1] - &c1[1]) * &(&s1[0] - &c1[0])) / &den; let uc = &(&(&s2[0] - &s1[0]) * &(&s1[1] - &c1[1]) - &(&s2[1] - &s1[1]) * &(&s1[0] - &c1[0])) / &den; if (&us == &T::zero() || &us == &T::one()) && (&T::zero() <= &uc && &uc <= &T::one()) || (&uc == &T::zero() || &uc == &T::one()) && (&T::zero() <= &us && &us <= &T::one()) { None } else if (&T::zero() < &us && &us < &T::one()) && (&T::zero() < &uc && &uc < &T::one()) { let x = &s1[0] + &(&us * &(&s2[0] - &s1[0])); let y = &s1[1] + &(&us * &(&s2[1] - &s1[1])); Some(([x, y], us, uc)) } else { None } } }