rcgal 0.2.2

Rust Computational Geometry Algorithms Library.
Documentation
use crate::{
    algorithm::location::point_2_line_segment_2::locate_point_2_line_segment_2,
    kernel::{number_type::NumberType, point_2::Point2, triangle_2::Triangle2},
};

use super::location_enum::{Point2Segment2Location, Point2Triangle2Location};

pub fn locate_point_2_triangle_2<T: NumberType>(
    point: &Point2<T>,
    triangle: &Triangle2<T>,
) -> Point2Triangle2Location {
    let edges = triangle.edges();
    let mut location = None;
    for edge in &edges {
        let edge_location = locate_point_2_line_segment_2(point, edge);
        match edge_location {
            Point2Segment2Location::On => return Point2Triangle2Location::On,
            Point2Segment2Location::Left => match location {
                Some(Point2Segment2Location::Right) => {
                    return Point2Triangle2Location::Outside;
                }
                None => {
                    location = Some(Point2Segment2Location::Left);
                }
                _ => {}
            },
            Point2Segment2Location::Right => match location {
                Some(Point2Segment2Location::Left) => {
                    return Point2Triangle2Location::Outside;
                }
                None => {
                    location = Some(Point2Segment2Location::Right);
                }
                _ => {}
            },
            _ => {
                return Point2Triangle2Location::Outside;
            }
        }
    }
    return Point2Triangle2Location::Inside;
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_locate_point_2_triangle_2() {
        let point = Point2::new(1.0, 1.0);
        let triangle = Triangle2::new(
            Point2::new(0.0, 0.0),
            Point2::new(2.0, 0.0),
            Point2::new(0.0, 2.0),
        );
        assert_eq!(
            locate_point_2_triangle_2(&point, &triangle),
            Point2Triangle2Location::On
        );

        let point = Point2::new(3.0, 3.0);
        assert_eq!(
            locate_point_2_triangle_2(&point, &triangle),
            Point2Triangle2Location::Outside
        );

        let point = Point2::new(1.0, 0.5);
        assert_eq!(
            locate_point_2_triangle_2(&point, &triangle),
            Point2Triangle2Location::Inside
        );
    }
}