1
1
use { Intersection , Plane , Polygon , Splitter } ;
2
+ use is_zero;
2
3
3
4
use binary_space_partition:: { BspNode , Plane as BspPlane , PlaneCut } ;
4
5
use euclid:: { TypedPoint3D , TypedVector3D } ;
@@ -18,15 +19,29 @@ impl<T, U> BspPlane for Polygon<T, U> where
18
19
fn cut ( & self , mut poly : Self ) -> PlaneCut < Self > {
19
20
debug ! ( "\t Cutting anchor {} by {}" , poly. anchor, self . anchor) ;
20
21
trace ! ( "\t \t base {:?}" , self . plane) ;
21
- let dist = self . plane . signed_distance_sum_to ( & poly) ;
22
22
23
- match self . intersect ( & poly) {
24
- Intersection :: Coplanar if dist. approx_eq ( & T :: zero ( ) ) => {
25
- debug ! ( "\t \t Coplanar and matching (dist = {:?})" , dist) ;
23
+ let ( intersection, dist) = if self . plane . normal
24
+ . dot ( poly. plane . normal )
25
+ . approx_eq ( & T :: one ( ) )
26
+ {
27
+ debug ! ( "\t \t Normals roughly match" ) ;
28
+ ( Intersection :: Coplanar , self . plane . offset - poly. plane . offset )
29
+ } else {
30
+ let is = self . intersect ( & poly) ;
31
+ let dist = self . plane . signed_distance_sum_to ( & poly) ;
32
+ ( is, dist)
33
+ } ;
34
+
35
+ match intersection {
36
+ //Note: we deliberately make the comparison wider than just with T::epsilon().
37
+ // This is done to avoid mistakenly ordering items that should be on the same
38
+ // plane but end up slightly different due to the floating point precision.
39
+ Intersection :: Coplanar if is_zero ( dist) => {
40
+ debug ! ( "\t \t Coplanar at {:?}" , dist) ;
26
41
PlaneCut :: Sibling ( poly)
27
42
}
28
43
Intersection :: Coplanar | Intersection :: Outside => {
29
- debug ! ( "\t \t Coplanar at {:?}" , dist) ;
44
+ debug ! ( "\t \t Outside at {:?}" , dist) ;
30
45
if dist > T :: zero ( ) {
31
46
PlaneCut :: Cut {
32
47
front : vec ! [ poly] ,
0 commit comments