multiple matrix by tuple
This commit is contained in:
@@ -8,3 +8,4 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
approx = "0.4"
|
||||
structs = { path = "../structs" }
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#[macro_use]
|
||||
extern crate approx;
|
||||
|
||||
use structs::Tuple;
|
||||
|
||||
use std::ops::Index;
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -28,6 +30,22 @@ impl 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)
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<usize> for Matrix {
|
||||
@@ -57,6 +75,56 @@ impl PartialEq for Matrix {
|
||||
}
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
sum
|
||||
}
|
||||
|
||||
fn calc_val_for_mul_tuple(&self, row: usize, tuple: &Tuple) -> f32 {
|
||||
(self.matrix[row][0] * tuple.x()) +
|
||||
(self.matrix[row][1] * tuple.y()) +
|
||||
(self.matrix[row][2] * tuple.z()) +
|
||||
(self.matrix[row][3] * tuple.w())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Mul<Matrix> 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));
|
||||
}
|
||||
rows.push(cols);
|
||||
}
|
||||
Matrix::new(rows)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl std::ops::Mul<Tuple> for Matrix {
|
||||
type Output = Tuple;
|
||||
|
||||
fn mul(self, _rhs: Tuple) -> Tuple {
|
||||
Tuple::new(
|
||||
self.calc_val_for_mul_tuple(0, &_rhs),
|
||||
self.calc_val_for_mul_tuple(1, &_rhs),
|
||||
self.calc_val_for_mul_tuple(2, &_rhs),
|
||||
self.calc_val_for_mul_tuple(3, &_rhs),
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -194,4 +262,19 @@ mod tests {
|
||||
|
||||
assert_eq!(matrix_a * matrix_b, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiply_by_tuple() {
|
||||
let matrix = Matrix::from_array([
|
||||
[1.0, 2.0, 3.0, 4.0],
|
||||
[2.0, 4.0, 4.0, 2.0],
|
||||
[8.0, 6.0, 4.0, 1.0],
|
||||
[0.0, 0.0, 0.0, 1.0],
|
||||
]);
|
||||
|
||||
let tuple = Tuple::new(1.0, 2.0, 3.0, 1.0);
|
||||
let expected = Tuple::new(18.0, 24.0, 33.0, 1.0);
|
||||
|
||||
assert_eq!(matrix * tuple, expected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,10 @@ impl Tuple {
|
||||
self.z
|
||||
}
|
||||
|
||||
pub fn w(&self) -> f32 {
|
||||
self.w
|
||||
}
|
||||
|
||||
pub fn is_point(&self) -> bool {
|
||||
self.w == 1.0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user