use crate::mat;
use crate::mat::Matrix;
pub trait AlgebraMut: mat::MatrixMut {
#[inline]
fn rotate_180_in_place(&mut self) {
self.as_slice_mut().as_mut().reverse();
}
#[inline]
fn reflect_horizontal_in_place(&mut self) {
for row in self.rows_mut() {
row.reverse();
}
}
#[inline]
fn reflect_vertical_in_place(&mut self) {
let width = self.width();
let height = self.height();
let slice = self.as_slice_mut();
for y in 0..(height / 2) {
for x in 0..width {
slice.swap(y * width + x, (height - y - 1) * width + x);
}
}
}
}
pub trait Algebra: mat::Matrix<Item: Clone> {
#[inline]
fn rotate_180(&self) -> mat::MatrixVec<Self::Item> {
let mut new = self.to_owned();
new.rotate_180_in_place();
new
}
#[inline]
fn rotate_90_right(&self) -> mat::MatrixVec<Self::Item> {
let mut new = self.to_owned();
new.swap_size();
for (row, x) in self.rows().zip((0..new.width()).rev()) {
for (item, y) in row.iter().zip(0..) {
new[(x, y)] = item.clone();
}
}
new
}
#[inline]
fn rotate_90_left(&self) -> mat::MatrixVec<Self::Item> {
let mut new = self.to_owned();
new.swap_size();
for (row, x) in self.rows().zip(0..) {
for (item, y) in row.iter().zip((0..new.height()).rev()) {
new[(x, y)] = item.clone();
}
}
new
}
#[inline]
fn transpose(&self) -> mat::MatrixVec<Self::Item> {
let mut new = self.to_owned();
new.swap_size();
for y in 0..self.height() {
for x in 0..self.width() {
new[(y, x)] = self[(x, y)].clone();
}
}
new
}
#[inline]
fn reflect_horizontal(&self) -> mat::MatrixVec<Self::Item> {
let mut new = self.to_owned();
new.reflect_horizontal_in_place();
new
}
#[inline]
fn reflect_vertical(&self) -> mat::MatrixVec<Self::Item> {
let mut new = self.to_owned();
new.reflect_vertical_in_place();
new
}
}
impl<M> AlgebraMut for M where M: mat::MatrixMut {}
impl<M> Algebra for M where M: mat::Matrix<Item: Clone> {}