use std::num::{Zero, One}; use structs::vec::{Vec2, Vec3, Vec2MulRhs, Vec3MulRhs}; use structs::mat::{Mat1, Mat2, Mat3, Mat3MulRhs, Mat2MulRhs}; use traits::operations::Inv; use traits::structure::{Row, Col}; // some specializations: impl Inv for Mat1 { #[inline] fn inv_cpy(m: &Mat1) -> Option> { let mut res = m.clone(); if res.inv() { Some(res) } else { None } } #[inline] fn inv(&mut self) -> bool { if self.m11.is_zero() { false } else { let _1: N = One::one(); self.m11 = _1 / self.m11; true } } } impl Inv for Mat2 { #[inline] fn inv_cpy(m: &Mat2) -> Option> { let mut res = m.clone(); if res.inv() { Some(res) } else { None } } #[inline] fn inv(&mut self) -> bool { let det = self.m11 * self.m22 - self.m21 * self.m12; if det.is_zero() { false } else { *self = Mat2::new( self.m22 / det , -self.m12 / det, -self.m21 / det, self.m11 / det); true } } } impl Inv for Mat3 { #[inline] fn inv_cpy(m: &Mat3) -> Option> { let mut res = m.clone(); if res.inv() { Some(res) } else { None } } #[inline] fn inv(&mut self) -> bool { let minor_m12_m23 = self.m22 * self.m33 - self.m32 * self.m23; let minor_m11_m23 = self.m21 * self.m33 - self.m31 * self.m23; let minor_m11_m22 = self.m21 * self.m32 - self.m31 * self.m22; let det = self.m11 * minor_m12_m23 - self.m12 * minor_m11_m23 + self.m13 * minor_m11_m22; if det.is_zero() { false } else { *self = Mat3::new( (minor_m12_m23 / det), ((self.m13 * self.m32 - self.m33 * self.m12) / det), ((self.m12 * self.m23 - self.m22 * self.m13) / det), (-minor_m11_m23 / det), ((self.m11 * self.m33 - self.m31 * self.m13) / det), ((self.m13 * self.m21 - self.m23 * self.m11) / det), (minor_m11_m22 / det), ((self.m12 * self.m31 - self.m32 * self.m11) / det), ((self.m11 * self.m22 - self.m21 * self.m12) / det) ); true } } } impl Row> for Mat3 { #[inline] fn nrows(&self) -> uint { 3 } #[inline] fn row(&self, i: uint) -> Vec3 { match i { 0 => Vec3::new(self.m11.clone(), self.m12.clone(), self.m13.clone()), 1 => Vec3::new(self.m21.clone(), self.m22.clone(), self.m23.clone()), 2 => Vec3::new(self.m31.clone(), self.m32.clone(), self.m33.clone()), _ => fail!("Index out of range: 3d matrices do not have " + i.to_str() + " rows.") } } #[inline] fn set_row(&mut self, i: uint, r: Vec3) { match i { 0 => { self.m11 = r.x.clone(); self.m12 = r.y.clone(); self.m13 = r.z; }, 1 => { self.m21 = r.x.clone(); self.m22 = r.y.clone(); self.m23 = r.z; }, 2 => { self.m31 = r.x.clone(); self.m32 = r.y.clone(); self.m33 = r.z; }, _ => fail!("Index out of range: 3d matrices do not have " + i.to_str() + " rows.") } } } impl Col> for Mat3 { #[inline] fn ncols(&self) -> uint { 3 } #[inline] fn col(&self, i: uint) -> Vec3 { match i { 0 => Vec3::new(self.m11.clone(), self.m21.clone(), self.m31.clone()), 1 => Vec3::new(self.m12.clone(), self.m22.clone(), self.m32.clone()), 2 => Vec3::new(self.m13.clone(), self.m23.clone(), self.m33.clone()), _ => fail!("Index out of range: 3d matrices do not have " + i.to_str() + " cols.") } } #[inline] fn set_col(&mut self, i: uint, r: Vec3) { match i { 0 => { self.m11 = r.x.clone(); self.m21 = r.y.clone(); self.m31 = r.z; }, 1 => { self.m12 = r.x.clone(); self.m22 = r.y.clone(); self.m32 = r.z; }, 2 => { self.m13 = r.x.clone(); self.m23 = r.y.clone(); self.m33 = r.z; }, _ => fail!("Index out of range: 3d matrices do not have " + i.to_str() + " cols.") } } } impl + Add> Mat3MulRhs> for Mat3 { #[inline] fn binop(left: &Mat3, right: &Mat3) -> Mat3 { Mat3::new( left.m11 * right.m11 + left.m12 * right.m21 + left.m13 * right.m31, left.m11 * right.m12 + left.m12 * right.m22 + left.m13 * right.m32, left.m11 * right.m13 + left.m12 * right.m23 + left.m13 * right.m33, left.m21 * right.m11 + left.m22 * right.m21 + left.m23 * right.m31, left.m21 * right.m12 + left.m22 * right.m22 + left.m23 * right.m32, left.m21 * right.m13 + left.m22 * right.m23 + left.m23 * right.m33, left.m31 * right.m11 + left.m32 * right.m21 + left.m33 * right.m31, left.m31 * right.m12 + left.m32 * right.m22 + left.m33 * right.m32, left.m31 * right.m13 + left.m32 * right.m23 + left.m33 * right.m33 ) } } impl + Add> Mat2MulRhs> for Mat2 { #[inline(always)] fn binop(left: &Mat2, right: &Mat2) -> Mat2 { Mat2::new( left.m11 * right.m11 + left.m12 * right.m21, left.m11 * right.m12 + left.m12 * right.m22, left.m21 * right.m11 + left.m22 * right.m21, left.m21 * right.m12 + left.m22 * right.m22 ) } } impl + Add> Mat3MulRhs> for Vec3 { #[inline(always)] fn binop(left: &Mat3, right: &Vec3) -> Vec3 { Vec3::new( left.m11 * right.x + left.m12 * right.y + left.m13 * right.z, left.m21 * right.x + left.m22 * right.y + left.m23 * right.z, left.m31 * right.x + left.m32 * right.y + left.m33 * right.z ) } } impl + Add> Vec3MulRhs> for Mat3 { #[inline(always)] fn binop(left: &Vec3, right: &Mat3) -> Vec3 { Vec3::new( left.x * right.m11 + left.y * right.m21 + left.z * right.m31, left.x * right.m12 + left.y * right.m22 + left.z * right.m32, left.x * right.m13 + left.y * right.m23 + left.z * right.m33 ) } } impl + Add> Vec2MulRhs> for Mat2 { #[inline(always)] fn binop(left: &Vec2, right: &Mat2) -> Vec2 { Vec2::new( left.x * right.m11 + left.y * right.m21, left.x * right.m12 + left.y * right.m22 ) } } impl + Add> Mat2MulRhs> for Vec2 { #[inline(always)] fn binop(left: &Mat2, right: &Vec2) -> Vec2 { Vec2::new( left.m11 * right.x + left.m12 * right.y, left.m21 * right.x + left.m22 * right.y ) } }