diff --git a/matrix/src/lib.rs b/matrix/src/lib.rs index 08d9c5e..0c63cc0 100644 --- a/matrix/src/lib.rs +++ b/matrix/src/lib.rs @@ -6,74 +6,50 @@ use structs::Tuple; use std::ops::Index; #[derive(Debug)] -pub struct Matrix { - matrix: Vec>, +pub struct Matrix { + matrix: [[f32; COUNT]; COUNT], } -impl Matrix { - pub fn new(matrix: Vec>) -> Matrix { +impl Matrix { + pub fn new() -> Matrix { + Matrix { + matrix: [[0f32; COUNT]; COUNT], + } + } + + pub fn from_array(matrix: [[f32; COUNT]; COUNT]) -> Matrix { Matrix { matrix: matrix, } } - pub fn from_array(matrix: [[f32; 4]; 4]) -> Matrix { - let mut m = Vec::with_capacity(4); - for row in 0..matrix.len() { - let mut r = Vec::with_capacity(4); - for col in 0..matrix[row].len() { - r.push(matrix[row][col]); - } - m.push(r); + pub fn identity() -> Matrix { + let mut m = Matrix::new(); + for i in 0..m.matrix.len() { + m.matrix[i][i] = 1.0; } - Matrix { - 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], - ]) + m } pub fn transpose(&mut self) { - self.matrix = vec![ - vec![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], ], - vec![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], ], + let tmp = [ + [self.matrix[0][0], self.matrix[1][0], self.matrix[2][0], self.matrix[3][0], ], + [self.matrix[0][1], self.matrix[1][1], self.matrix[2][1], self.matrix[3][1], ], + [self.matrix[0][2], self.matrix[1][2], self.matrix[2][2], self.matrix[3][2], ], + [self.matrix[0][3], self.matrix[1][3], self.matrix[2][3], self.matrix[3][3], ], ]; + self.matrix = tmp; } } -impl Index for Matrix { - type Output = Vec; +impl Index for Matrix { + type Output = [f32; COUNT]; fn index(&self, index: usize) -> &Self::Output { &self.matrix[index] } } -impl PartialEq for Matrix { +impl PartialEq for Matrix { fn eq(&self, _rhs: &Self) -> bool { if self.matrix.len() != _rhs.matrix.len() { return false; @@ -93,8 +69,8 @@ impl PartialEq for Matrix { } } -impl Matrix { - fn calc_val_for_mul(&self, row: usize, rhs: &Matrix, col: usize) -> f32 { +impl Matrix { + fn calc_val_for_mul(&self, row: usize, rhs: &Matrix, col: usize) -> f32 { let mut sum = 0.0; for i in 0..self.matrix.len() { sum += self.matrix[row][i] * rhs.matrix[i][col]; @@ -110,26 +86,22 @@ impl Matrix { } } -impl std::ops::Mul for Matrix { - type Output = Matrix; +impl std::ops::Mul> for Matrix { + type Output = Matrix; - fn mul(self, _rhs: Matrix) -> Matrix { - let row_count = self.matrix.len(); - let col_count = self.matrix[0].len(); - let mut rows = Vec::with_capacity(row_count); - for row in 0..row_count { - let mut cols = Vec::with_capacity(col_count); - for col in 0..col_count { - cols.push(self.calc_val_for_mul(row, &_rhs, col)); + fn mul(self, _rhs: Matrix) -> Matrix { + let mut result = [[0f32; COUNT]; COUNT]; + for row in 0..COUNT { + for col in 0..COUNT { + result[row][col] = self.calc_val_for_mul(row, &_rhs, col); } - rows.push(cols); } - Matrix::new(rows) + Matrix::from_array(result) } } -impl std::ops::Mul for Matrix { +impl std::ops::Mul for Matrix { type Output = Tuple; fn mul(self, _rhs: Tuple) -> Tuple { @@ -149,14 +121,14 @@ mod tests { #[test] fn matrix_4x4() { - let m = vec![ - vec![1.0, 2.0, 3.0, 4.0], - vec![5.5, 6.5, 7.5, 8.5], - vec![9.0, 10.0, 11.0, 12.0], - vec![13.5, 14.5, 15.5, 16.5], + let m = [ + [1.0, 2.0, 3.0, 4.0], + [5.5, 6.5, 7.5, 8.5], + [9.0, 10.0, 11.0, 12.0], + [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!(4.0, matrix[0][3]); assert_eq!(5.5, matrix[1][0]); @@ -187,11 +159,11 @@ mod tests { #[test] fn matrix_2x2() { - let m = vec![ - vec![-3.0, 5.0,], - vec![1.0, 2.0,], + let m = [ + [-3.0, 5.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!(5.0, matrix[0][1]); assert_eq!(1.0, matrix[1][0]); @@ -200,13 +172,13 @@ mod tests { #[test] fn matrix_3x3() { - let m = vec![ - vec![-3.0, 5.0, 0.0], - vec![1.0, -2.0, -7.0], - vec![0.0, 1.0, 1.0], + let m = [ + [-3.0, 5.0, 0.0], + [1.0, -2.0, -7.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!(-2.0, matrix[1][1]); assert_eq!(1.0, matrix[2][2]); @@ -214,44 +186,44 @@ mod tests { #[test] fn matrix_equality_a() { - let a = vec![ - vec![1.0, 2.0, 3.0, 4.0], - vec![5.0, 6.0, 7.0, 8.0], - vec![9.0, 8.0, 7.0, 6.0], - vec![5.0, 4.0, 3.0, 2.0], + let a = [ + [1.0, 2.0, 3.0, 4.0], + [5.0, 6.0, 7.0, 8.0], + [9.0, 8.0, 7.0, 6.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![ - vec![1.0, 2.0, 3.0, 4.0], - vec![5.0, 6.0, 7.0, 8.0], - vec![9.0, 8.0, 7.0, 6.0], - vec![5.0, 4.0, 3.0, 2.0], + let b = [ + [1.0, 2.0, 3.0, 4.0], + [5.0, 6.0, 7.0, 8.0], + [9.0, 8.0, 7.0, 6.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); } #[test] fn matrix_equality_b() { - let a = vec![ - vec![1.0, 2.0, 3.0, 4.0], - vec![5.0, 6.0, 7.0, 8.0], - vec![9.0, 8.0, 7.0, 6.0], - vec![5.0, 4.0, 3.0, 2.0], + let a = [ + [1.0, 2.0, 3.0, 4.0], + [5.0, 6.0, 7.0, 8.0], + [9.0, 8.0, 7.0, 6.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![ - vec![2.0, 3.0, 4.0, 5.0], - vec![6.0, 7.0, 8.0, 9.0], - vec![8.0, 7.0, 6.0, 5.0], - vec![4.0, 3.0, 2.0, 1.0], + let b = [ + [2.0, 3.0, 4.0, 5.0], + [6.0, 7.0, 8.0, 9.0], + [8.0, 7.0, 6.0, 5.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); } @@ -320,7 +292,7 @@ mod tests { let t = 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] @@ -346,6 +318,6 @@ mod tests { fn transpose_identity() { let mut m = Matrix::identity(); m.transpose(); - assert_eq!(m, Matrix::identity()); + assert_eq!(m, Matrix::<4>::identity()); } }