switched from vec to array with const generic size
This commit is contained in:
@@ -6,74 +6,50 @@ use structs::Tuple;
|
|||||||
use std::ops::Index;
|
use std::ops::Index;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Matrix {
|
pub struct Matrix<const COUNT: usize> {
|
||||||
matrix: Vec<Vec<f32>>,
|
matrix: [[f32; COUNT]; COUNT],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Matrix {
|
impl<const COUNT: usize> Matrix<COUNT> {
|
||||||
pub fn new(matrix: Vec<Vec<f32>>) -> Matrix {
|
pub fn new() -> Matrix<COUNT> {
|
||||||
|
Matrix {
|
||||||
|
matrix: [[0f32; COUNT]; COUNT],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_array(matrix: [[f32; COUNT]; COUNT]) -> Matrix<COUNT> {
|
||||||
Matrix {
|
Matrix {
|
||||||
matrix: matrix,
|
matrix: matrix,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_array(matrix: [[f32; 4]; 4]) -> Matrix {
|
pub fn identity() -> Matrix<COUNT> {
|
||||||
let mut m = Vec::with_capacity(4);
|
let mut m = Matrix::new();
|
||||||
for row in 0..matrix.len() {
|
for i in 0..m.matrix.len() {
|
||||||
let mut r = Vec::with_capacity(4);
|
m.matrix[i][i] = 1.0;
|
||||||
for col in 0..matrix[row].len() {
|
|
||||||
r.push(matrix[row][col]);
|
|
||||||
}
|
|
||||||
m.push(r);
|
|
||||||
}
|
}
|
||||||
Matrix {
|
m
|
||||||
matrix: m,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_empty(row_count: usize, col_count: usize) -> Matrix {
|
|
||||||
let mut rows = Vec::with_capacity(row_count);
|
|
||||||
for _ in 0..row_count {
|
|
||||||
let mut col = Vec::with_capacity(col_count);
|
|
||||||
for _ in 0..col_count {
|
|
||||||
col.push(0.0);
|
|
||||||
}
|
|
||||||
rows.push(col);
|
|
||||||
}
|
|
||||||
Matrix::new(rows)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_empty_4() -> Matrix {
|
|
||||||
Matrix::new_empty(4, 4)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn identity() -> Matrix {
|
|
||||||
Matrix::new(vec![
|
|
||||||
vec![1.0, 0.0, 0.0, 0.0],
|
|
||||||
vec![0.0, 1.0, 0.0, 0.0],
|
|
||||||
vec![0.0, 0.0, 1.0, 0.0],
|
|
||||||
vec![0.0, 0.0, 0.0, 1.0],
|
|
||||||
])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transpose(&mut self) {
|
pub fn transpose(&mut self) {
|
||||||
self.matrix = vec![
|
let tmp = [
|
||||||
vec![self.matrix[0][0], self.matrix[1][0], self.matrix[2][0], self.matrix[3][0], ],
|
[self.matrix[0][0], self.matrix[1][0], self.matrix[2][0], self.matrix[3][0], ],
|
||||||
vec![self.matrix[0][1], self.matrix[1][1], self.matrix[2][1], self.matrix[3][1], ],
|
[self.matrix[0][1], self.matrix[1][1], self.matrix[2][1], self.matrix[3][1], ],
|
||||||
vec![self.matrix[0][2], self.matrix[1][2], self.matrix[2][2], self.matrix[3][2], ],
|
[self.matrix[0][2], self.matrix[1][2], self.matrix[2][2], self.matrix[3][2], ],
|
||||||
vec![self.matrix[0][3], self.matrix[1][3], self.matrix[2][3], self.matrix[3][3], ],
|
[self.matrix[0][3], self.matrix[1][3], self.matrix[2][3], self.matrix[3][3], ],
|
||||||
];
|
];
|
||||||
|
self.matrix = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Index<usize> for Matrix {
|
impl<const COUNT: usize> Index<usize> for Matrix<COUNT> {
|
||||||
type Output = Vec<f32>;
|
type Output = [f32; COUNT];
|
||||||
fn index(&self, index: usize) -> &Self::Output {
|
fn index(&self, index: usize) -> &Self::Output {
|
||||||
&self.matrix[index]
|
&self.matrix[index]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for Matrix {
|
impl<const COUNT: usize> PartialEq for Matrix<COUNT> {
|
||||||
fn eq(&self, _rhs: &Self) -> bool {
|
fn eq(&self, _rhs: &Self) -> bool {
|
||||||
if self.matrix.len() != _rhs.matrix.len() {
|
if self.matrix.len() != _rhs.matrix.len() {
|
||||||
return false;
|
return false;
|
||||||
@@ -93,8 +69,8 @@ impl PartialEq for Matrix {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Matrix {
|
impl<const COUNT: usize> Matrix<COUNT> {
|
||||||
fn calc_val_for_mul(&self, row: usize, rhs: &Matrix, col: usize) -> f32 {
|
fn calc_val_for_mul(&self, row: usize, rhs: &Matrix<COUNT>, col: usize) -> f32 {
|
||||||
let mut sum = 0.0;
|
let mut sum = 0.0;
|
||||||
for i in 0..self.matrix.len() {
|
for i in 0..self.matrix.len() {
|
||||||
sum += self.matrix[row][i] * rhs.matrix[i][col];
|
sum += self.matrix[row][i] * rhs.matrix[i][col];
|
||||||
@@ -110,26 +86,22 @@ impl Matrix {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::ops::Mul<Matrix> for Matrix {
|
impl<const COUNT: usize> std::ops::Mul<Matrix<COUNT>> for Matrix<COUNT> {
|
||||||
type Output = Matrix;
|
type Output = Matrix<COUNT>;
|
||||||
|
|
||||||
fn mul(self, _rhs: Matrix) -> Matrix {
|
fn mul(self, _rhs: Matrix<COUNT>) -> Matrix<COUNT> {
|
||||||
let row_count = self.matrix.len();
|
let mut result = [[0f32; COUNT]; COUNT];
|
||||||
let col_count = self.matrix[0].len();
|
for row in 0..COUNT {
|
||||||
let mut rows = Vec::with_capacity(row_count);
|
for col in 0..COUNT {
|
||||||
for row in 0..row_count {
|
result[row][col] = self.calc_val_for_mul(row, &_rhs, col);
|
||||||
let mut cols = Vec::with_capacity(col_count);
|
|
||||||
for col in 0..col_count {
|
|
||||||
cols.push(self.calc_val_for_mul(row, &_rhs, col));
|
|
||||||
}
|
}
|
||||||
rows.push(cols);
|
|
||||||
}
|
}
|
||||||
Matrix::new(rows)
|
Matrix::from_array(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::ops::Mul<Tuple> for Matrix {
|
impl<const COUNT: usize> std::ops::Mul<Tuple> for Matrix<COUNT> {
|
||||||
type Output = Tuple;
|
type Output = Tuple;
|
||||||
|
|
||||||
fn mul(self, _rhs: Tuple) -> Tuple {
|
fn mul(self, _rhs: Tuple) -> Tuple {
|
||||||
@@ -149,14 +121,14 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn matrix_4x4() {
|
fn matrix_4x4() {
|
||||||
let m = vec![
|
let m = [
|
||||||
vec![1.0, 2.0, 3.0, 4.0],
|
[1.0, 2.0, 3.0, 4.0],
|
||||||
vec![5.5, 6.5, 7.5, 8.5],
|
[5.5, 6.5, 7.5, 8.5],
|
||||||
vec![9.0, 10.0, 11.0, 12.0],
|
[9.0, 10.0, 11.0, 12.0],
|
||||||
vec![13.5, 14.5, 15.5, 16.5],
|
[13.5, 14.5, 15.5, 16.5],
|
||||||
];
|
];
|
||||||
|
|
||||||
let matrix = Matrix::new(m);
|
let matrix = Matrix::from_array(m);
|
||||||
assert_eq!(1.0, matrix[0][0]);
|
assert_eq!(1.0, matrix[0][0]);
|
||||||
assert_eq!(4.0, matrix[0][3]);
|
assert_eq!(4.0, matrix[0][3]);
|
||||||
assert_eq!(5.5, matrix[1][0]);
|
assert_eq!(5.5, matrix[1][0]);
|
||||||
@@ -187,11 +159,11 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn matrix_2x2() {
|
fn matrix_2x2() {
|
||||||
let m = vec![
|
let m = [
|
||||||
vec![-3.0, 5.0,],
|
[-3.0, 5.0,],
|
||||||
vec![1.0, 2.0,],
|
[1.0, 2.0,],
|
||||||
];
|
];
|
||||||
let matrix = Matrix::new(m);
|
let matrix = Matrix::from_array(m);
|
||||||
assert_eq!(-3.0, matrix[0][0]);
|
assert_eq!(-3.0, matrix[0][0]);
|
||||||
assert_eq!(5.0, matrix[0][1]);
|
assert_eq!(5.0, matrix[0][1]);
|
||||||
assert_eq!(1.0, matrix[1][0]);
|
assert_eq!(1.0, matrix[1][0]);
|
||||||
@@ -200,13 +172,13 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn matrix_3x3() {
|
fn matrix_3x3() {
|
||||||
let m = vec![
|
let m = [
|
||||||
vec![-3.0, 5.0, 0.0],
|
[-3.0, 5.0, 0.0],
|
||||||
vec![1.0, -2.0, -7.0],
|
[1.0, -2.0, -7.0],
|
||||||
vec![0.0, 1.0, 1.0],
|
[0.0, 1.0, 1.0],
|
||||||
];
|
];
|
||||||
|
|
||||||
let matrix = Matrix::new(m);
|
let matrix = Matrix::from_array(m);
|
||||||
assert_eq!(-3.0, matrix[0][0]);
|
assert_eq!(-3.0, matrix[0][0]);
|
||||||
assert_eq!(-2.0, matrix[1][1]);
|
assert_eq!(-2.0, matrix[1][1]);
|
||||||
assert_eq!(1.0, matrix[2][2]);
|
assert_eq!(1.0, matrix[2][2]);
|
||||||
@@ -214,44 +186,44 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn matrix_equality_a() {
|
fn matrix_equality_a() {
|
||||||
let a = vec![
|
let a = [
|
||||||
vec![1.0, 2.0, 3.0, 4.0],
|
[1.0, 2.0, 3.0, 4.0],
|
||||||
vec![5.0, 6.0, 7.0, 8.0],
|
[5.0, 6.0, 7.0, 8.0],
|
||||||
vec![9.0, 8.0, 7.0, 6.0],
|
[9.0, 8.0, 7.0, 6.0],
|
||||||
vec![5.0, 4.0, 3.0, 2.0],
|
[5.0, 4.0, 3.0, 2.0],
|
||||||
];
|
];
|
||||||
let m_a = Matrix::new(a);
|
let m_a = Matrix::from_array(a);
|
||||||
|
|
||||||
let b = vec![
|
let b = [
|
||||||
vec![1.0, 2.0, 3.0, 4.0],
|
[1.0, 2.0, 3.0, 4.0],
|
||||||
vec![5.0, 6.0, 7.0, 8.0],
|
[5.0, 6.0, 7.0, 8.0],
|
||||||
vec![9.0, 8.0, 7.0, 6.0],
|
[9.0, 8.0, 7.0, 6.0],
|
||||||
vec![5.0, 4.0, 3.0, 2.0],
|
[5.0, 4.0, 3.0, 2.0],
|
||||||
];
|
];
|
||||||
|
|
||||||
let m_b = Matrix::new(b);
|
let m_b = Matrix::from_array(b);
|
||||||
|
|
||||||
assert_eq!(m_a, m_b);
|
assert_eq!(m_a, m_b);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn matrix_equality_b() {
|
fn matrix_equality_b() {
|
||||||
let a = vec![
|
let a = [
|
||||||
vec![1.0, 2.0, 3.0, 4.0],
|
[1.0, 2.0, 3.0, 4.0],
|
||||||
vec![5.0, 6.0, 7.0, 8.0],
|
[5.0, 6.0, 7.0, 8.0],
|
||||||
vec![9.0, 8.0, 7.0, 6.0],
|
[9.0, 8.0, 7.0, 6.0],
|
||||||
vec![5.0, 4.0, 3.0, 2.0],
|
[5.0, 4.0, 3.0, 2.0],
|
||||||
];
|
];
|
||||||
let m_a = Matrix::new(a);
|
let m_a = Matrix::from_array(a);
|
||||||
|
|
||||||
let b = vec![
|
let b = [
|
||||||
vec![2.0, 3.0, 4.0, 5.0],
|
[2.0, 3.0, 4.0, 5.0],
|
||||||
vec![6.0, 7.0, 8.0, 9.0],
|
[6.0, 7.0, 8.0, 9.0],
|
||||||
vec![8.0, 7.0, 6.0, 5.0],
|
[8.0, 7.0, 6.0, 5.0],
|
||||||
vec![4.0, 3.0, 2.0, 1.0],
|
[4.0, 3.0, 2.0, 1.0],
|
||||||
];
|
];
|
||||||
|
|
||||||
let m_b = Matrix::new(b);
|
let m_b = Matrix::from_array(b);
|
||||||
|
|
||||||
assert_ne!(m_a, m_b);
|
assert_ne!(m_a, m_b);
|
||||||
}
|
}
|
||||||
@@ -320,7 +292,7 @@ mod tests {
|
|||||||
let t = Tuple::new(1.0, 2.0, 3.0, 4.0);
|
let t = Tuple::new(1.0, 2.0, 3.0, 4.0);
|
||||||
let expected = Tuple::new(1.0, 2.0, 3.0, 4.0);
|
let expected = Tuple::new(1.0, 2.0, 3.0, 4.0);
|
||||||
|
|
||||||
assert_eq!(Matrix::identity() * t, expected);
|
assert_eq!(Matrix::<4>::identity() * t, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -346,6 +318,6 @@ mod tests {
|
|||||||
fn transpose_identity() {
|
fn transpose_identity() {
|
||||||
let mut m = Matrix::identity();
|
let mut m = Matrix::identity();
|
||||||
m.transpose();
|
m.transpose();
|
||||||
assert_eq!(m, Matrix::identity());
|
assert_eq!(m, Matrix::<4>::identity());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user