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