#![allow(dead_code)]
#[derive(Debug, Clone, Copy)]
pub struct LatticeDims {
pub x: usize,
pub y: usize,
pub z: usize,
}
impl LatticeDims {
pub fn total_points(&self) -> usize {
self.x * self.y * self.z
}
}
#[derive(Debug, Clone)]
pub struct LatticeMorph {
pub dims: LatticeDims,
pub displacements: Vec<[f32; 3]>,
pub weight: f32,
}
impl LatticeMorph {
pub fn new(x: usize, y: usize, z: usize) -> Self {
let dims = LatticeDims { x, y, z };
let n = dims.total_points();
LatticeMorph {
dims,
displacements: vec![[0.0; 3]; n],
weight: 0.0,
}
}
}
pub fn new_lattice_morph(x: usize, y: usize, z: usize) -> LatticeMorph {
LatticeMorph::new(x, y, z)
}
pub fn lattice_set_point(morph: &mut LatticeMorph, index: usize, disp: [f32; 3]) {
if index < morph.displacements.len() {
morph.displacements[index] = disp;
}
}
pub fn lattice_get_point(morph: &LatticeMorph, index: usize) -> [f32; 3] {
if index < morph.displacements.len() {
morph.displacements[index]
} else {
[0.0; 3]
}
}
pub fn lattice_set_weight(morph: &mut LatticeMorph, weight: f32) {
morph.weight = weight.clamp(0.0, 1.0);
}
pub fn lattice_point_count(morph: &LatticeMorph) -> usize {
morph.dims.total_points()
}
pub fn lattice_to_json(morph: &LatticeMorph) -> String {
format!(
r#"{{"dims":[{},{},{}],"weight":{:.4},"points":{}}}"#,
morph.dims.x,
morph.dims.y,
morph.dims.z,
morph.weight,
morph.displacements.len()
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_lattice_correct_point_count() {
let m = new_lattice_morph(2, 3, 4);
assert_eq!(lattice_point_count(&m), 24 ,);
}
#[test]
fn test_initial_weight_zero() {
let m = new_lattice_morph(2, 2, 2);
assert!((m.weight).abs() < 1e-6, );
}
#[test]
fn test_set_point_updates_displacement() {
let mut m = new_lattice_morph(2, 2, 2);
lattice_set_point(&mut m, 0, [1.0, 2.0, 3.0]);
let p = lattice_get_point(&m, 0);
assert!((p[0] - 1.0).abs() < 1e-5 ,);
}
#[test]
fn test_get_out_of_bounds_returns_zero() {
let m = new_lattice_morph(2, 2, 2);
let p = lattice_get_point(&m, 999);
assert!((p[0]).abs() < 1e-6, );
}
#[test]
fn test_set_weight_clamps() {
let mut m = new_lattice_morph(2, 2, 2);
lattice_set_weight(&mut m, 2.5);
assert!((m.weight - 1.0).abs() < 1e-5, );
}
#[test]
fn test_set_weight_negative_clamps() {
let mut m = new_lattice_morph(2, 2, 2);
lattice_set_weight(&mut m, -1.0);
assert!((m.weight).abs() < 1e-6, );
}
#[test]
fn test_to_json_contains_dims() {
let m = new_lattice_morph(3, 4, 5);
let j = lattice_to_json(&m);
assert!(j.contains("dims") ,);
}
#[test]
fn test_dims_total_points() {
let d = LatticeDims { x: 2, y: 3, z: 5 };
assert_eq!(d.total_points(), 30 ,);
}
#[test]
fn test_set_multiple_points() {
let mut m = new_lattice_morph(2, 2, 2);
lattice_set_point(&mut m, 1, [0.0, 1.0, 0.0]);
lattice_set_point(&mut m, 2, [0.0, 0.0, 1.0]);
assert!((lattice_get_point(&m, 1)[1] - 1.0).abs() < 1e-5, );
assert!((lattice_get_point(&m, 2)[2] - 1.0).abs() < 1e-5, );
}
#[test]
fn test_displacements_initialized_zero() {
let m = new_lattice_morph(3, 3, 3);
for d in &m.displacements {
assert!((d[0]).abs() < 1e-6, );
}
}
}