This splits up the types and supporting code for defining layers from the code for generating layers for a given mushroom.
93 lines
2.8 KiB
Rust
93 lines
2.8 KiB
Rust
use stl_io::{self, Vertex};
|
|
|
|
use crate::layers;
|
|
use crate::mushroom::{CapStyle, Mushroom};
|
|
|
|
fn stalk_layers(mushroom: &Mushroom, base: &Vertex, _resolution: f32) -> Vec<layers::Layer> {
|
|
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<layers::Layer> {
|
|
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<layers::Layer> {
|
|
let mut result: Vec<layers::Layer> = 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<layers::Layer> {
|
|
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<layers::Layer> = Vec::new();
|
|
layers.append(&mut stalk_layers);
|
|
layers.append(&mut cap_layers);
|
|
return layers::Layers { base, top, layers };
|
|
}
|