optimize the dilate operation

This commit is contained in:
2022-01-11 15:11:28 -08:00
parent 0ad013b275
commit af0e955b0f

View File

@@ -243,31 +243,41 @@ impl Region for Wrap {
pub struct Dilate {
inner: Box<dyn Region>,
rad: f32,
res: f32,
}
impl Dilate {
pub fn new<T: Region + 'static>(inner: T, rad: f32) -> Self {
Self { inner: Box::new(inner), rad }
pub fn new<T: Region + 'static>(inner: T, rad: f32, res: f32) -> Self {
Self { inner: Box::new(inner), rad, res }
}
pub fn new_iterated<T: Region + 'static>(inner: T, resolution: f32, iters: usize) -> Self {
let mut it = Self::new(inner, resolution);
for _ in 1..iters {
it = Self::new(it, resolution);
}
it
Self::new(inner, resolution * iters as f32, resolution)
}
}
#[typetag::serde]
impl Region for Dilate {
fn contains(&self, p: Meters) -> bool {
self.inner.contains(p)
|| self.inner.contains(p + Meters::new(self.rad, 0.0, 0.0))
|| self.inner.contains(p + Meters::new(0.0, -self.rad, 0.0))
|| self.inner.contains(p + Meters::new(0.0, self.rad, 0.0))
|| self.inner.contains(p + Meters::new(0.0, -self.rad, 0.0))
|| self.inner.contains(p + Meters::new(0.0, 0.0, self.rad))
|| self.inner.contains(p + Meters::new(0.0, 0.0, -self.rad))
let small = p - Meters::new(self.rad, self.rad, self.rad);
let large = p + Meters::new(self.rad, self.rad, self.rad);
let rad_iters = (self.rad / self.res).ceil() as i32;
let rad_range = -rad_iters..=rad_iters;
let rad_sq = self.rad * self.rad;
for zoff in rad_range.clone() {
for yoff in rad_range.clone() {
for xoff in rad_range.clone() {
let off = Meters::new(
xoff as f32 * self.res,
yoff as f32 * self.res,
zoff as f32 * self.res,
);
if off.mag_sq() <= rad_sq && self.inner.contains(p + off) {
return true;
}
}
}
}
false
}
}