home /
grad_rs /
src /
vec2.rs
vec2.rs
use std::f64;
use std::ops::{Index, IndexMut};
#[derive(Debug)]
pub struct Vec2<T: Copy> {
pub flat: Vec<T>,
pub columns: usize,
}
impl<T: Copy> Vec2<T> {
pub fn create(capacity: usize) -> Vec2<T> {
return Vec2 {
columns: 0,
flat: Vec::with_capacity(capacity)
}
}
pub fn push(&mut self, row: &[T]) {
if self.columns == 0 {
self.columns = row.len()
}
assert_eq!(row.len(), self.columns);
for val in row.iter() {
self.flat.push(*val);
}
}
pub fn iter(&self) -> Vec2Iterator<T> {
Vec2Iterator {
reference: self,
cursor: 0
}
}
pub fn len(&self) -> usize {
return self.flat.len() / self.columns
}
pub fn column(&self, col: usize) -> Vec<T> {
self.vertical_iter(col).collect()
}
pub fn divide(&self, first_percentage: usize) -> (Vec2<T>, Vec2<T>) {
let first_size = (self.len() as f64 / 100.0) as usize * first_percentage;
let mid = first_size * self.columns;
let end = self.flat.len();
let first = Vec2 { columns: self.columns, flat: self.flat[0..mid].to_vec() };
let second = Vec2 { columns: self.columns, flat: self.flat[mid..end].to_vec() };
return (first, second)
}
fn vertical_iter<'a>(&'a self, col: usize) -> impl Iterator<Item = T> + 'a {
self.iter()
.map(move |l| l[col])
}
}
impl Vec2<f64> {
pub fn scale_to(&self, range: (f64, f64)) -> Vec2<f64> {
let mut result = Vec2::create(self.flat.capacity());
let scaled: Vec<Vec<f64>> = (0..self.columns)
.map(|col| {
let mut c = self.column(col);
Vec2::scale_vector(&mut c, range);
return c
}).collect();
for y in 0..self.len() {
let line: Vec<f64> = (0..self.columns).map(|col| scaled[col][y]).collect();
result.push(&line)
}
result
}
fn scale_vector(vector: &mut Vec<f64>, range: (f64, f64)) {
let (min_range, max_range) = range;
let min = *vector.iter().min_by(|a, b| a.partial_cmp(b).unwrap()).unwrap();
let max = *vector.iter().max_by(|a, b| a.partial_cmp(b).unwrap()).unwrap();
let current_range = max - min;
let desired_range = max_range - min_range;
for value in vector.iter_mut() {
// Shift the value to be relative to the minimum value
let shifted_value = *value - min;
// Scale the shifted value to the range [0, 1]
let scaled_value = shifted_value / current_range;
// Scale the value to the desired range and shift it to the min_range
*value = scaled_value * desired_range + min_range;
}
}
}
pub struct Vec2Iterator<'a, T: Copy> {
reference: &'a Vec2<T>,
cursor: usize
}
impl<'a, T: Copy> Iterator for Vec2Iterator<'a, T> {
type Item = &'a [T];
fn next(&mut self) -> Option<Self::Item> {
if self.cursor >= self.reference.flat.len() {
return None;
}
let start = self.cursor;
let end = start + self.reference.columns;
self.cursor += self.reference.columns;
Some(&self.reference.flat[start..end])
}
}
impl<T: Copy> Index<usize> for Vec2<T> {
type Output = [T];
fn index(&self, row: usize) -> &Self::Output {
let start = self.columns * row;
let end = start + self.columns;
&self.flat[start..end]
}
}
impl<T: Copy> IndexMut<usize> for Vec2<T> {
fn index_mut(&mut self, row: usize) -> &mut Self::Output {
let start = self.columns * row;
let end = start + self.columns;
&mut self.flat[start..end]
}
}