rcgal 0.2.2

Rust Computational Geometry Algorithms Library.
Documentation
use crate::kernel::{number_type::NumberType, point_2::Point2, ray_2::Ray2};

use super::location_enum::Point2Ray2Location;

pub fn is_point_2_on_ray_2<T: NumberType>(p: &Point2<T>, r: &Ray2<T>) -> bool {
    if p.equals(&r.origin()) {
        return true;
    }
    let v = *p - r.origin();
    let cross = r.direction().cross(&v);
    let dot = r.direction().dot(&v);
    dot > T::zero() && cross.equals(T::zero())
}

pub fn locate_point_2_ray_2<T: NumberType>(p: &Point2<T>, r: &Ray2<T>) -> Point2Ray2Location {
    if is_point_2_on_ray_2(p, r) {
        return Point2Ray2Location::On;
    }
    let v = *p - r.origin();
    let cross = r.direction().cross(&v);
    if cross > T::default_eps() {
        return Point2Ray2Location::Left;
    } else if cross < -T::default_eps() {
        return Point2Ray2Location::Right;
    }
    return Point2Ray2Location::Collinear;
}

#[cfg(test)]
mod tests {
    use crate::kernel::vector_2::Vector2;

    use super::*;

    #[test]
    fn test_is_point_2_on_ray_2() {
        let r = Ray2::new(Point2::new(0.0, 0.0), Vector2::new(1.0, 0.0));
        let p = Point2::new(1.0, 0.0);
        assert_eq!(is_point_2_on_ray_2(&p, &r), true);

        let p = Point2::new(1.0, 1.0);
        assert_eq!(is_point_2_on_ray_2(&p, &r), false);

        let p = Point2::new(0.0, 0.0);
        assert_eq!(is_point_2_on_ray_2(&p, &r), true);

        let p = Point2::new(-1.0, 0.0);
        assert_eq!(is_point_2_on_ray_2(&p, &r), false);
    }

    #[test]
    fn test_locate_point_2_ray_2() {
        let r = Ray2::new(Point2::new(0.0, 0.0), Vector2::new(1.0, 0.0));
        let p = Point2::new(1.0, 0.0);
        assert_eq!(locate_point_2_ray_2(&p, &r), Point2Ray2Location::On);

        let p = Point2::new(1.0, 1.0);
        assert_eq!(locate_point_2_ray_2(&p, &r), Point2Ray2Location::Left);

        let p = Point2::new(0.0, 0.0);
        assert_eq!(locate_point_2_ray_2(&p, &r), Point2Ray2Location::On);

        let p = Point2::new(-1.0, 0.0);
        assert_eq!(locate_point_2_ray_2(&p, &r), Point2Ray2Location::Collinear);

        let p = Point2::new(1.0, -1.0);
        assert_eq!(locate_point_2_ray_2(&p, &r), Point2Ray2Location::Right);
    }
}