haar_lib/geom/
area_intersection_circle_polygon.rs

1//! 円と多角形の共通部分の面積
2
3use crate::geom::{intersect_circle_segment::*, *};
4
5/// 円と多角形の共通部分の面積を求める。
6pub fn area_intersection_circle_polygon(cl: Circle, ps: &[Vector], eps: Eps) -> f64 {
7    use self::IntersectCircleSegment::*;
8
9    let n = ps.len();
10    let mut ret = 0.0;
11
12    for i in 0..n {
13        let mut temp = 0.0;
14
15        let Circle {
16            center: c,
17            radius: r,
18        } = cl;
19        let p1 = ps[i];
20        let p2 = ps[(i + 1) % n];
21
22        let (t, res) = intersect_circle_segment(cl, Line::new(p1, p2), eps);
23
24        let d1 = (p1 - c).abs();
25        let d2 = (p2 - c).abs();
26
27        match res.len() {
28            0 => match t {
29                INSIDE => temp += (p1 - c).cross(p2 - c) / 2.0,
30                _ => temp += r * r * (p1 - c).angle_diff(p2 - c) / 2.0,
31            },
32            1 => {
33                let q = res[0];
34                if d1 >= r && d2 >= r {
35                    temp += r * r * (p1 - c).angle_diff(p2 - c) / 2.0;
36                } else if d1 >= r {
37                    temp += r * r * (p1 - c).angle_diff(q - c) / 2.0 + (q - c).cross(p2 - c) / 2.0
38                } else {
39                    temp += (p1 - c).cross(q - c) / 2.0 + r * r * (q - c).angle_diff(p2 - c) / 2.0
40                }
41            }
42            _ => {
43                let q1 = res[0];
44                let q2 = res[1];
45
46                temp += r * r * (p1 - c).angle_diff(q1 - c) / 2.0
47                    + (q1 - c).cross(q2 - c) / 2.0
48                    + r * r * (q2 - c).angle_diff(p2 - c) / 2.0
49            }
50        }
51
52        ret += temp;
53    }
54
55    ret
56}