use euclid::{
default::{Rect, Transform3D},
point3, rect, vec3, Angle,
};
use plane_split::{Clipper, Plane, Polygon};
use std::f64::consts::FRAC_PI_4;
#[ test]
fn clip_in() {
let plane = Plane::from_unnormalized(vec3(1 .0 , 0 .0 , 1 .0 ), 20 .0 )
.unwrap()
.unwrap();
let mut clipper = Clipper::new();
clipper.add(plane);
let poly = Polygon::from_points(
[
point3(-10 .0 , -10 .0 , 0 .0 ),
point3(10 .0 , -10 .0 , 0 .0 ),
point3(10 .0 , 10 .0 , 0 .0 ),
point3(-10 .0 , 10 .0 , 0 .0 ),
],
0 ,
)
.unwrap();
let results = clipper.clip(poly.clone());
assert_eq!(results[0 ], poly);
assert_eq!(results.len(), 1 );
}
#[ test]
fn clip_out() {
let plane = Plane::from_unnormalized(vec3(1 .0 , 0 .0 , 1 .0 ), -20 .0 )
.unwrap()
.unwrap();
let mut clipper = Clipper::new();
clipper.add(plane);
let poly = Polygon::from_points(
[
point3(-10 .0 , -10 .0 , 0 .0 ),
point3(10 .0 , -10 .0 , 0 .0 ),
point3(10 .0 , 10 .0 , 0 .0 ),
point3(-10 .0 , 10 .0 , 0 .0 ),
],
0 ,
)
.unwrap();
let results = clipper.clip(poly);
assert!(results.is_empty());
}
#[ test]
fn clip_parallel() {
let plane = Plane {
normal: vec3(0 .0 , 0 .0 , 1 .0 ),
offset: 0 .0 ,
};
let mut clipper = Clipper::new();
clipper.add(plane);
let poly = Polygon::from_points(
[
point3(-10 .0 , -10 .0 , 0 .0 ),
point3(10 .0 , -10 .0 , 0 .0 ),
point3(10 .0 , 10 .0 , 0 .0 ),
point3(-10 .0 , 10 .0 , 0 .0 ),
],
0 ,
)
.unwrap();
let results = clipper.clip(poly);
assert!(results.is_empty());
}
#[ test]
fn clip_repeat() {
let plane = Plane::from_unnormalized(vec3(1 .0 , 0 .0 , 1 .0 ), 0 .0 )
.unwrap()
.unwrap();
let mut clipper = Clipper::new();
clipper.add(plane.clone());
clipper.add(plane.clone());
let poly = Polygon::from_points(
[
point3(-10 .0 , -10 .0 , 0 .0 ),
point3(10 .0 , -10 .0 , 0 .0 ),
point3(10 .0 , 10 .0 , 0 .0 ),
point3(-10 .0 , 10 .0 , 0 .0 ),
],
0 ,
)
.unwrap();
let results = clipper.clip(poly);
assert_eq!(results.len(), 1 );
assert!(plane.signed_distance_sum_to(&results[0 ]) > 0 .0 );
}
#[ test]
fn clip_transformed() {
let t_rot: Transform3D<f64> = Transform3D::rotation(0 .0 , 1 .0 , 0 .0 , Angle::radians(-FRAC_PI_4));
let t_div: Transform3D<f64> = Transform3D::perspective(5 .0 );
let transform = t_rot.then(&t_div);
let polygon = Polygon::from_rect(rect(-10 .0 , -10 .0 , 20 .0 , 20 .0 ), 0 );
let bounds: Rect<f64> = rect(-1 .0 , -1 .0 , 2 .0 , 2 .0 );
let mut clipper = Clipper::new();
let results = clipper.clip_transformed(polygon, &transform, Some(bounds));
// iterating enforces the transformation checks/unwraps
assert_ne!(0 , results.unwrap().count());
}
#[ test]
fn clip_badly_transformed() {
let mut tx = Transform3D::<f64>::identity();
tx.m14 = -0 .0000001 ;
tx.m44 = 0 .0 ;
let mut clipper = Clipper::new();
let polygon = Polygon::from_rect(rect(-10 .0 , -10 .0 , 20 .0 , 20 .0 ), 0 );
let results = clipper.clip_transformed(polygon, &tx, None);
assert!(results.is_err());
}
#[ test]
fn clip_near_coplanar() {
let tx = Transform3D::<f64>::new(
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 ,
);
let mut clipper = Clipper::new();
let polygon = Polygon::from_rect(rect(0 .0 , 0 .0 , 1703 .0 , 4020 .0 ), 0 );
let bounds1 = rect(0 .0 , -430 .0 , 2048 .0 , 2048 .0 );
let results1 = clipper.clip_transformed(polygon.clone(), &tx, Some(bounds1));
assert_ne!(0 , results1.unwrap().count());
let bounds2 = rect(0 .0 , 0 .0 , 816 .0 , 1039 .0 );
let results2 = clipper.clip_transformed(polygon, &tx, Some(bounds2));
assert_ne!(0 , results2.unwrap().count());
}
Messung V0.5 in Prozent C=72 H=97 G=85
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-19)
¤
*© Formatika GbR, Deutschland