1 use euclid::{point3, rect, vec3, Angle, Rect, Transform3D};
2 use plane_split::{Clipper, Plane, Polygon};
3 
4 use std::f32::consts::FRAC_PI_4;
5 
6 #[test]
clip_in()7 fn clip_in() {
8     let plane: Plane<f32, ()> = Plane::from_unnormalized(vec3(1.0, 0.0, 1.0), 20.0)
9         .unwrap()
10         .unwrap();
11     let mut clipper = Clipper::new();
12     clipper.add(plane);
13 
14     let poly = Polygon::from_points(
15         [
16             point3(-10.0, -10.0, 0.0),
17             point3(10.0, -10.0, 0.0),
18             point3(10.0, 10.0, 0.0),
19             point3(-10.0, 10.0, 0.0),
20         ],
21         0,
22     )
23     .unwrap();
24 
25     let results = clipper.clip(poly.clone());
26     assert_eq!(results[0], poly);
27     assert_eq!(results.len(), 1);
28 }
29 
30 #[test]
clip_out()31 fn clip_out() {
32     let plane: Plane<f32, ()> = Plane::from_unnormalized(vec3(1.0, 0.0, 1.0), -20.0)
33         .unwrap()
34         .unwrap();
35     let mut clipper = Clipper::new();
36     clipper.add(plane);
37 
38     let poly = Polygon::from_points(
39         [
40             point3(-10.0, -10.0, 0.0),
41             point3(10.0, -10.0, 0.0),
42             point3(10.0, 10.0, 0.0),
43             point3(-10.0, 10.0, 0.0),
44         ],
45         0,
46     )
47     .unwrap();
48 
49     let results = clipper.clip(poly);
50     assert!(results.is_empty());
51 }
52 
53 #[test]
clip_parallel()54 fn clip_parallel() {
55     let plane: Plane<f32, ()> = Plane {
56         normal: vec3(0.0, 0.0, 1.0),
57         offset: 0.0,
58     };
59     let mut clipper = Clipper::new();
60     clipper.add(plane);
61 
62     let poly = Polygon::from_points(
63         [
64             point3(-10.0, -10.0, 0.0),
65             point3(10.0, -10.0, 0.0),
66             point3(10.0, 10.0, 0.0),
67             point3(-10.0, 10.0, 0.0),
68         ],
69         0,
70     )
71     .unwrap();
72 
73     let results = clipper.clip(poly);
74     assert!(results.is_empty());
75 }
76 
77 #[test]
clip_repeat()78 fn clip_repeat() {
79     let plane: Plane<f32, ()> = Plane::from_unnormalized(vec3(1.0, 0.0, 1.0), 0.0)
80         .unwrap()
81         .unwrap();
82     let mut clipper = Clipper::new();
83     clipper.add(plane.clone());
84     clipper.add(plane.clone());
85 
86     let poly = Polygon::from_points(
87         [
88             point3(-10.0, -10.0, 0.0),
89             point3(10.0, -10.0, 0.0),
90             point3(10.0, 10.0, 0.0),
91             point3(-10.0, 10.0, 0.0),
92         ],
93         0,
94     )
95     .unwrap();
96 
97     let results = clipper.clip(poly);
98     assert_eq!(results.len(), 1);
99     assert!(plane.signed_distance_sum_to(&results[0]) > 0.0);
100 }
101 
102 #[test]
clip_transformed()103 fn clip_transformed() {
104     let t_rot: Transform3D<f32, (), ()> =
105         Transform3D::rotation(0.0, 1.0, 0.0, Angle::radians(-FRAC_PI_4));
106     let t_div: Transform3D<f32, (), ()> = Transform3D::perspective(5.0);
107     let transform = t_rot.then(&t_div);
108 
109     let polygon = Polygon::from_rect(rect(-10.0, -10.0, 20.0, 20.0), 0);
110     let bounds: Rect<f32, ()> = rect(-1.0, -1.0, 2.0, 2.0);
111 
112     let mut clipper = Clipper::new();
113     let results = clipper.clip_transformed(polygon, &transform, Some(bounds));
114     // iterating enforces the transformation checks/unwraps
115     assert_ne!(0, results.unwrap().count());
116 }
117 
118 #[test]
clip_badly_transformed()119 fn clip_badly_transformed() {
120     let mut tx = Transform3D::<f32, (), ()>::identity();
121     tx.m14 = -0.0000001;
122     tx.m44 = 0.0;
123 
124     let mut clipper = Clipper::new();
125     let polygon = Polygon::from_rect(rect(-10.0, -10.0, 20.0, 20.0), 0);
126     let results = clipper.clip_transformed(polygon, &tx, None);
127     assert!(results.is_err());
128 }
129 
130 #[test]
clip_near_coplanar()131 fn clip_near_coplanar() {
132     let tx = Transform3D::<f32, (), ()>::new(
133         1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, -960.0, -625.0, 1.0, -1.0, 100.0, -2852.0, 0.0, 1.0,
134     );
135     let mut clipper = Clipper::new();
136     let polygon = Polygon::from_rect(rect(0.0, 0.0, 1703.0, 4020.0), 0);
137 
138     let bounds1 = rect(0.0, -430.0, 2048.0, 2048.0);
139     let results1 = clipper.clip_transformed(polygon.clone(), &tx, Some(bounds1));
140     assert_ne!(0, results1.unwrap().count());
141 
142     let bounds2 = rect(0.0, 0.0, 816.0, 1039.0);
143     let results2 = clipper.clip_transformed(polygon, &tx, Some(bounds2));
144     assert_ne!(0, results2.unwrap().count());
145 }
146