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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use crate::objects::{Curve, Face};
use super::{CurveFaceIntersection, SurfaceSurfaceIntersection};
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct FaceFaceIntersection {
pub intersection_curves: [Curve; 2],
pub intersection_intervals: CurveFaceIntersection,
}
impl FaceFaceIntersection {
pub fn compute(faces: [&Face; 2]) -> Option<Self> {
let surfaces = faces.map(|face| face.surface());
let intersection_curves =
SurfaceSurfaceIntersection::compute(surfaces)?.intersection_curves;
let curve_face_intersections = {
let [curve_a, curve_b] = &intersection_curves;
let [face_a, face_b] = faces;
[(curve_a, face_a), (curve_b, face_b)].map(|(curve, face)| {
CurveFaceIntersection::compute(curve, face)
})
};
let intersection_intervals = {
let [a, b] = curve_face_intersections;
a.merge(&b)
};
if intersection_intervals.is_empty() {
return None;
}
Some(Self {
intersection_curves,
intersection_intervals,
})
}
}
#[cfg(test)]
mod tests {
use pretty_assertions::assert_eq;
use crate::{
algorithms::intersect::CurveFaceIntersection,
objects::{Curve, Face, Surface},
};
use super::FaceFaceIntersection;
#[test]
fn compute_no_intersection() {
#[rustfmt::skip]
let points = [
[1., 1.],
[2., 1.],
[2., 2.],
[1., 2.],
];
let surfaces = [Surface::xy_plane(), Surface::xz_plane()];
let [a, b] = surfaces.map(|surface| {
Face::build(surface).polygon_from_points(points).into_face()
});
let intersection = FaceFaceIntersection::compute([&a, &b]);
assert!(intersection.is_none());
}
#[test]
fn compute_one_intersection() {
#[rustfmt::skip]
let points = [
[-1., -1.],
[ 1., -1.],
[ 1., 1.],
[-1., 1.],
];
let surfaces = [Surface::xy_plane(), Surface::xz_plane()];
let [a, b] = surfaces.map(|surface| {
Face::build(surface).polygon_from_points(points).into_face()
});
let intersection = FaceFaceIntersection::compute([&a, &b]);
let expected_curves = surfaces.map(|surface| {
Curve::build(surface).line_from_points([[0., 0.], [1., 0.]])
});
let expected_intervals =
CurveFaceIntersection::from_intervals([[[-1.], [1.]]]);
assert_eq!(
intersection,
Some(FaceFaceIntersection {
intersection_curves: expected_curves,
intersection_intervals: expected_intervals
})
);
}
}