use stl_io::{self, Vertex}; use crate::layers; use crate::mushroom::{CapStyle, Mushroom}; fn stalk_layers(mushroom: &Mushroom, base: &Vertex, _resolution: f32) -> Vec { let stalk_top = Vertex::new([base[0], base[1], base[2] + mushroom.stalk_h]); return [ layers::Layer { center: base.clone(), radius: mushroom.stalk_r, }, layers::Layer { center: stalk_top, radius: mushroom.stalk_r, }, ] .to_vec(); } fn cap_layers_cylinder(mushroom: &Mushroom, base: &Vertex) -> Vec { let top = Vertex::new([base[0], base[1], base[2] + mushroom.cap_h]); return [ layers::Layer { center: base.clone(), radius: mushroom.cap_r, }, layers::Layer { center: top, radius: mushroom.cap_r, }, ] .to_vec(); } fn cap_layers_dome(mushroom: &Mushroom, base: &Vertex, resolution: f32) -> Vec { let mut result: Vec = Vec::with_capacity((mushroom.cap_h / resolution) as usize); let mut height = 0.0; loop { // A = mushroom.cap_h // B = mushroom.cap_r // x=B/π * arccos(y/A) let radius = (mushroom.cap_r / std::f32::consts::PI) * (height / mushroom.cap_h).acos(); result.push(layers::Layer { center: Vertex::new([base[0], base[1], base[2] + height]), radius: radius, }); height += resolution; if height >= mushroom.cap_h { break; } } return result; } fn cap_layers(mushroom: &Mushroom, base: &Vertex, resolution: f32) -> Vec { match mushroom.cap_style { CapStyle::Cylinder => cap_layers_cylinder(mushroom, base), CapStyle::Dome => cap_layers_dome(mushroom, base, resolution), CapStyle::Pointed => cap_layers_dome(mushroom, base, resolution), } } pub fn mushroom(mushroom: &Mushroom, resolution: f32) -> layers::Layers { let _vertical_steps = (mushroom.height() / resolution) as u32; let base = Vertex::new([0.0, 0.0, 0.0]); // Get layers for the stalk. let mut stalk_layers = stalk_layers(mushroom, &base, resolution); // Get layers for the cap. let cap_base = stalk_layers.last().unwrap().center; let mut cap_layers = cap_layers(mushroom, &cap_base, resolution); // The very top of the mushroom is directly above the top layer of the cap (or even with it) // at the exact height of the total mushroom. let cap_top = &cap_layers.last().unwrap().center; let top = Vertex::new([cap_top[0], cap_top[1], base[2] + mushroom.height()]); // Assemble the final Layers object. let mut layers: Vec = Vec::new(); layers.append(&mut stalk_layers); layers.append(&mut cap_layers); return layers::Layers { base, top, layers }; }