use glam::DVec3;
#[derive(Debug, Clone)]
pub(crate) struct TwoDArray {
rows: Vec<Vec<f64>>,
cols: usize,
}
impl TwoDArray {
pub fn new() -> Self {
Self {
rows: Vec::new(),
cols: 0,
}
}
pub fn allocate(&mut self, nrows: usize, ncols: usize) {
self.cols = ncols;
self.rows = vec![vec![0.0; ncols]; nrows];
}
pub fn set_dvec3(&mut self, n: usize, v: DVec3) {
let row = &mut self.rows[n];
row[0] = v.x;
row[1] = v.y;
row[2] = v.z;
}
pub fn get_dvec3(&self, n: usize) -> DVec3 {
let row = &self.rows[n];
DVec3::new(row[0], row[1], row[2])
}
pub fn rotate_down(&mut self, limit: usize) {
self.rows[..=limit].rotate_left(1);
}
pub fn downsample(&mut self, limit: usize) {
for i in 1..limit {
self.rows.swap(i, 2 * i);
}
}
pub fn offset_rows(&self, offset: usize) -> OffsetRows<'_> {
OffsetRows {
array: self,
offset,
}
}
}
pub(crate) struct OffsetRows<'a> {
array: &'a TwoDArray,
offset: usize,
}
impl<'a> OffsetRows<'a> {
pub fn get_dvec3(&self, i: usize) -> DVec3 {
self.array.get_dvec3(self.offset + i)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_allocate_and_access() {
let mut arr = TwoDArray::new();
arr.allocate(3, 3);
arr.set_dvec3(0, DVec3::new(1.0, 2.0, 3.0));
assert_eq!(arr.get_dvec3(0), DVec3::new(1.0, 2.0, 3.0));
assert_eq!(arr.get_dvec3(1), DVec3::ZERO);
}
#[test]
fn test_rotate_down() {
let mut arr = TwoDArray::new();
arr.allocate(4, 1);
arr.rows[0][0] = 0.0;
arr.rows[1][0] = 1.0;
arr.rows[2][0] = 2.0;
arr.rows[3][0] = 3.0;
arr.rotate_down(3);
assert_eq!(arr.rows[0][0], 1.0);
assert_eq!(arr.rows[1][0], 2.0);
assert_eq!(arr.rows[2][0], 3.0);
assert_eq!(arr.rows[3][0], 0.0);
}
#[test]
fn test_downsample() {
let mut arr = TwoDArray::new();
arr.allocate(5, 1);
for i in 0..5 {
arr.rows[i][0] = i as f64;
}
arr.downsample(3);
assert_eq!(arr.rows[0][0], 0.0);
assert_eq!(arr.rows[1][0], 2.0);
assert_eq!(arr.rows[2][0], 4.0);
}
}