nalgebra/src/mat_spec.rs

110 lines
2.5 KiB
Rust
Raw Normal View History

2013-06-29 08:34:45 +08:00
use std::num::{Zero, One};
use mat::{Mat1, Mat2, Mat3};
2013-08-17 23:50:01 +08:00
use traits::ring::DivisionRing;
2013-06-29 08:34:45 +08:00
use traits::inv::Inv;
// some specializations:
impl<N: DivisionRing + Clone>
2013-08-05 16:13:44 +08:00
Inv for Mat1<N> {
2013-08-05 16:15:11 +08:00
#[inline]
fn inverse(&self) -> Option<Mat1<N>> {
let mut res : Mat1<N> = self.clone();
if res.inplace_inverse() {
Some(res)
}
else {
None
}
2013-08-05 16:13:44 +08:00
}
2013-06-29 08:34:45 +08:00
2013-08-05 16:15:11 +08:00
#[inline]
fn inplace_inverse(&mut self) -> bool {
if self.m11.is_zero() {
false
}
else {
self.m11 = One::one::<N>() / self.m11;
true
}
}
2013-06-29 08:34:45 +08:00
}
impl<N: DivisionRing + Clone>
2013-08-05 16:13:44 +08:00
Inv for Mat2<N> {
2013-08-05 16:15:11 +08:00
#[inline]
fn inverse(&self) -> Option<Mat2<N>> {
let mut res : Mat2<N> = self.clone();
if res.inplace_inverse() {
Some(res)
}
else {
None
}
2013-08-05 16:13:44 +08:00
}
2013-06-29 08:34:45 +08:00
2013-08-05 16:15:11 +08:00
#[inline]
fn inplace_inverse(&mut self) -> bool {
let det = self.m11 * self.m22 - self.m21 * self.m12;
2013-06-29 08:34:45 +08:00
2013-08-05 16:15:11 +08:00
if det.is_zero() {
false
}
else {
2013-08-17 23:50:01 +08:00
*self = Mat2::new(
self.m22 / det , -self.m12 / det,
-self.m21 / det, self.m11 / det);
2013-06-29 08:34:45 +08:00
2013-08-05 16:15:11 +08:00
true
}
}
2013-06-29 08:34:45 +08:00
}
impl<N: DivisionRing + Clone>
2013-08-05 16:13:44 +08:00
Inv for Mat3<N> {
2013-08-05 16:15:11 +08:00
#[inline]
fn inverse(&self) -> Option<Mat3<N>> {
let mut res = self.clone();
if res.inplace_inverse() {
Some(res)
}
else {
None
}
2013-08-05 16:13:44 +08:00
}
2013-06-29 08:34:45 +08:00
2013-08-05 16:15:11 +08:00
#[inline]
fn inplace_inverse(&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(
2013-08-08 02:53:51 +08:00
(minor_m12_m23 / det),
2013-08-05 16:15:11 +08:00
((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
}
}
2013-06-29 08:34:45 +08:00
}