use crate::math::{Point, Real, Vector};
use crate::query::{self, Ray};
pub fn clip_halfspace_polygon(
center: &Point<Real>,
normal: &Vector<Real>,
polygon: &[Point<Real>],
result: &mut Vec<Point<Real>>,
) {
result.clear();
if polygon.is_empty() {
return;
}
let keep_point = |pt: &Point<Real>| (pt - center).dot(normal) <= 0.0;
let last_pt = polygon.last().unwrap();
let mut last_keep = keep_point(last_pt);
if last_keep {
result.push(*last_pt);
}
for i in 0..polygon.len() {
let pt = &polygon[i];
let keep = keep_point(pt);
if keep != last_keep {
let prev_i = if i == 0 { polygon.len() - 1 } else { i - 1 };
let prev_pt = &polygon[prev_i];
let ray = Ray::new(*prev_pt, pt - prev_pt);
if let Some(time_of_impact) =
query::details::ray_toi_with_halfspace(center, normal, &ray)
{
if time_of_impact > 0.0 && time_of_impact < 1.0 {
result.push(ray.origin + ray.dir * time_of_impact)
}
}
last_keep = keep;
}
if keep && i != polygon.len() - 1 {
result.push(*pt);
}
}
}