nalgebra/src/mat_spec.rs

112 lines
2.7 KiB
Rust
Raw Normal View History

2013-06-29 08:34:45 +08:00
use std::num::{Zero, One};
use mat::{Mat1, Mat2, Mat3};
use traits::division_ring::DivisionRing;
use traits::inv::Inv;
// some specializations:
impl<N: Copy + DivisionRing>
Inv for Mat1<N>
{
#[inline]
fn inverse(&self) -> Option<Mat1<N>>
2013-06-29 08:34:45 +08:00
{
let mut res : Mat1<N> = copy *self;
if res.inplace_inverse()
{ Some(res) }
else
{ None }
2013-06-29 08:34:45 +08:00
}
#[inline]
fn inplace_inverse(&mut self) -> bool
2013-06-29 08:34:45 +08:00
{
if self.mij[0].is_zero()
{ false }
else
{
self.mij[0] = One::one::<N>() / self.mij[0];
true
}
2013-06-29 08:34:45 +08:00
}
}
impl<N: Copy + DivisionRing>
Inv for Mat2<N>
{
#[inline]
fn inverse(&self) -> Option<Mat2<N>>
2013-06-29 08:34:45 +08:00
{
let mut res : Mat2<N> = copy *self;
if res.inplace_inverse()
{ Some(res) }
else
{ None }
2013-06-29 08:34:45 +08:00
}
#[inline]
fn inplace_inverse(&mut self) -> bool
2013-06-29 08:34:45 +08:00
{
let det = self.mij[0 * 2 + 0] * self.mij[1 * 2 + 1] - self.mij[1 * 2 + 0] * self.mij[0 * 2 + 1];
if det.is_zero()
{ false }
else
{
*self = Mat2::new([self.mij[1 * 2 + 1] / det , -self.mij[0 * 2 + 1] / det,
-self.mij[1 * 2 + 0] / det, self.mij[0 * 2 + 0] / det]);
2013-06-29 08:34:45 +08:00
true
}
2013-06-29 08:34:45 +08:00
}
}
impl<N: Copy + DivisionRing>
Inv for Mat3<N>
{
#[inline]
fn inverse(&self) -> Option<Mat3<N>>
2013-06-29 08:34:45 +08:00
{
let mut res = copy *self;
if res.inplace_inverse()
{ Some(res) }
else
{ None }
2013-06-29 08:34:45 +08:00
}
#[inline]
fn inplace_inverse(&mut self) -> bool
2013-06-29 08:34:45 +08:00
{
let minor_m12_m23 = self.mij[1 * 3 + 1] * self.mij[2 * 3 + 2] - self.mij[2 * 3 + 1] * self.mij[1 * 3 + 2];
let minor_m11_m23 = self.mij[1 * 3 + 0] * self.mij[2 * 3 + 2] - self.mij[2 * 3 + 0] * self.mij[1 * 3 + 2];
let minor_m11_m22 = self.mij[1 * 3 + 0] * self.mij[2 * 3 + 1] - self.mij[2 * 3 + 0] * self.mij[1 * 3 + 1];
let det = self.mij[0 * 3 + 0] * minor_m12_m23
- self.mij[0 * 3 + 1] * minor_m11_m23
+ self.mij[0 * 3 + 2] * minor_m11_m22;
if det.is_zero()
{ false }
else
{
*self = Mat3::new( [
(minor_m12_m23 / det),
((self.mij[0 * 3 + 2] * self.mij[2 * 3 + 1] - self.mij[2 * 3 + 2] * self.mij[0 * 3 + 1]) / det),
((self.mij[0 * 3 + 1] * self.mij[1 * 3 + 2] - self.mij[1 * 3 + 1] * self.mij[0 * 3 + 2]) / det),
(-minor_m11_m23 / det),
((self.mij[0 * 3 + 0] * self.mij[2 * 3 + 2] - self.mij[2 * 3 + 0] * self.mij[0 * 3 + 2]) / det),
((self.mij[0 * 3 + 2] * self.mij[1 * 3 + 0] - self.mij[1 * 3 + 2] * self.mij[0 * 3 + 0]) / det),
(minor_m11_m22 / det),
((self.mij[0 * 3 + 1] * self.mij[2 * 3 + 0] - self.mij[2 * 3 + 1] * self.mij[0 * 3 + 0]) / det),
((self.mij[0 * 3 + 0] * self.mij[1 * 3 + 1] - self.mij[1 * 3 + 0] * self.mij[0 * 3 + 1]) / det)
] );
true
}
2013-06-29 08:34:45 +08:00
}
}