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