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