parry3d/query/clip/
clip_halfspace_polygon.rs1use crate::math::{Point, Real, Vector};
2use crate::query::{self, Ray};
3use alloc::vec::Vec;
4
5pub fn clip_halfspace_polygon(
12 center: &Point<Real>,
13 normal: &Vector<Real>,
14 polygon: &[Point<Real>],
15 result: &mut Vec<Point<Real>>,
16) {
17 result.clear();
18
19 if polygon.is_empty() {
20 return;
21 }
22
23 let keep_point = |pt: &Point<Real>| (pt - center).dot(normal) <= 0.0;
24 let last_pt = polygon.last().unwrap();
25 let mut last_keep = keep_point(last_pt);
26
27 if last_keep {
28 result.push(*last_pt);
29 }
30
31 for i in 0..polygon.len() {
32 let pt = &polygon[i];
33 let keep = keep_point(pt);
34
35 if keep != last_keep {
36 let prev_i = if i == 0 { polygon.len() - 1 } else { i - 1 };
39 let prev_pt = &polygon[prev_i];
40 let ray = Ray::new(*prev_pt, pt - prev_pt);
41
42 if let Some(time_of_impact) =
43 query::details::ray_toi_with_halfspace(center, normal, &ray)
44 {
45 if time_of_impact > 0.0 && time_of_impact < 1.0 {
46 result.push(ray.origin + ray.dir * time_of_impact)
47 }
48 }
49
50 last_keep = keep;
51 }
52
53 if keep && i != polygon.len() - 1 {
54 result.push(*pt);
55 }
56 }
57}