rcgal 0.2.2

Rust Computational Geometry Algorithms Library.
Documentation
use crate::{
    algorithm::location::{
        location_enum::{Point2ArcSegment2Location, Point2Circle2Location},
        point_2_arc_segment_2::locate_point_2_arc_segment_2,
        point_2_circle_segment_2::locate_point_2_circle_segment_2,
    },
    kernel::{
        circle_segment_2::CircleSegment2, number_type::NumberType, point_2::Point2,
        segment_2::Segment2,
    },
};

use super::circle_segment_2_circle_segment_2::circle_segment_2_circle_segment_2_intersection;

pub fn is_circle_segment_2_arc_segment_2_intersected<T: NumberType>(
    circle_segment: &impl Segment2<T>,
    arc_segment: &impl Segment2<T>,
) -> bool {
    let points = circle_segment_2_arc_segment_2_intersection(circle_segment, arc_segment);
    !points.is_empty()
}

pub fn circle_segment_2_arc_segment_2_intersection<T: NumberType>(
    circle_segment: &impl Segment2<T>,
    arc_segment: &impl Segment2<T>,
) -> Vec<Point2<T>> {
    let support_circle_segment = CircleSegment2::new(arc_segment.center(), arc_segment.radius());
    let points =
        circle_segment_2_circle_segment_2_intersection(&support_circle_segment, circle_segment);
    let mut result = Vec::new();
    for point in &points {
        let location_arc = locate_point_2_arc_segment_2(point, arc_segment);
        let location_circle = locate_point_2_circle_segment_2(point, circle_segment);
        if location_arc == Point2ArcSegment2Location::On
            && location_circle == Point2Circle2Location::On
        {
            result.push(point.clone());
        }
    }
    result
}

#[cfg(test)]
mod tests {
    use std::f64::consts::PI;

    use crate::kernel::arc_segment_2::ArcSegment2;

    use super::*;

    #[test]
    fn test_is_circle_segment_2_arc_segment_2_intersected() {
        let circle_segment = CircleSegment2::new(Point2::new(0.0, 0.0), 5.0);

        let arc_segment_b =
            ArcSegment2::new(CircleSegment2::new(Point2::new(0.0, 0.0), 5.0), 0.0, PI);
        assert_eq!(
            is_circle_segment_2_arc_segment_2_intersected(&circle_segment, &arc_segment_b),
            false
        );

        let arc_segment_b =
            ArcSegment2::new(CircleSegment2::new(Point2::new(5.0, 0.0), 5.0), 0.0, PI);
        assert_eq!(
            is_circle_segment_2_arc_segment_2_intersected(&circle_segment, &arc_segment_b),
            true
        );
    }

    #[test]
    fn test_circle_segment_2_arc_segment_2_intersection() {
        let circle_segment = CircleSegment2::new(Point2::new(0.0, 0.0), 5.0);

        let arc_segment_b =
            ArcSegment2::new(CircleSegment2::new(Point2::new(0.0, 0.0), 5.0), 0.0, PI);
        assert_eq!(
            circle_segment_2_arc_segment_2_intersection(&circle_segment, &arc_segment_b),
            Vec::new()
        );

        let arc_segment_b =
            ArcSegment2::new(CircleSegment2::new(Point2::new(5.0, 0.0), 5.0), 0.0, PI);
        assert_eq!(
            circle_segment_2_arc_segment_2_intersection(&circle_segment, &arc_segment_b),
            vec![Point2::new(2.5, 2.5 * 3.0.sqrt()),]
        );
    }
}