use crate::gradient::*;
use crate::mesh::*;
use crate::mesh_3d::index_3d::*;
use crate::mesh_source::*;
pub fn repr_mesh_with_gradient_3d(mesh: &(impl Mesh + Index3D), gradient: &Gradient) -> String {
let mut output = String::new();
let (width, height, depth) = mesh.shape();
for z in 0..depth {
for y in 0..height {
for x in 0..width {
let c = match mesh.xyz_to_index(x, y, z) {
Ok(index) => {
let distance = gradient.get_distance(index);
if distance >= i32::MAX as f32 || distance <= i32::MIN as f32 {
'?'
} else {
let mut modulo = (distance.round() as i32) % 10;
if modulo < 0 {
modulo += 10;
}
let base0: u32 = '0' as u32;
char::from_u32(base0 + (modulo as u32)).unwrap_or('E')
}
}
Err(_) => Source2DFromText::DEFAULT_WALL_CHAR,
};
output.push(c);
}
output.push('\n');
}
for _ in 0..width {
output.push(Source2DFromText::DEFAULT_SEP_CHAR);
}
output.push('\n');
}
output
}
#[cfg(test)]
mod tests {
use super::*;
use crate::mesh_3d::full_3d::*;
#[test]
fn test_repr_distance_full_rectangle() {
let rect = Full3D::new(5, 4, 3);
let mut grad = Gradient::from_mesh(&rect);
let repr1 = repr_mesh_with_gradient_3d(&rect, &grad);
assert_eq!(
"?????\n?????\n?????\n?????\n-----\n?????\n?????\n?????\n?????\n-----\n?????\n?????\n?????\n?????\n-----\n",
repr1.as_str()
);
grad.set_distance(18, 0.0);
let repr2 = repr_mesh_with_gradient_3d(&rect, &grad);
assert_eq!(
"?????\n?????\n?????\n???0?\n-----\n?????\n?????\n?????\n?????\n-----\n?????\n?????\n?????\n?????\n-----\n",
repr2.as_str()
);
grad.spread_forward(&rect, 0.0);
let repr3 = repr_mesh_with_gradient_3d(&rect, &grad);
assert_eq!(
"?????\n?????\n??111\n?3101\n-----\n?????\n?3323\n53212\n42111\n-----\n54444\n43333\n43323\n43222\n-----\n",
repr3.as_str()
);
grad.spread(&rect);
let repr4 = repr_mesh_with_gradient_3d(&rect, &grad);
assert_eq!(
"44333\n43222\n32111\n32101\n-----\n54434\n43323\n43212\n32111\n-----\n54444\n43333\n43323\n43222\n-----\n",
repr4.as_str()
);
}
}