|
|
|
@ -19,6 +19,7 @@ |
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
//
|
|
|
|
use std::ops::{Add, Sub, Neg, Mul, Div};
|
|
|
|
use std::fmt::Debug;
|
|
|
|
|
|
|
|
use crate::Vector;
|
|
|
|
use crate::trigonometry::Trig;
|
|
|
|
@ -28,30 +29,34 @@ pub struct TMatrix<T>( (T, T, T, T) |
|
|
|
, (T, T, T, T)
|
|
|
|
, (T, T, T, T)
|
|
|
|
, (T, T, T, T) )
|
|
|
|
where T: Add + Sub + Neg + Mul + Div + Trig + From<i32> + Copy;
|
|
|
|
where T: Add + Sub + Neg + Mul + Div + Debug + Trig + From<i32> + Copy;
|
|
|
|
|
|
|
|
pub fn unit<T>() -> TMatrix<T>
|
|
|
|
where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
|
|
|
|
+ Mul<Output = T> + Div<Output = T> + Trig + From<i32> + Copy {
|
|
|
|
+ Mul<Output = T> + Div<Output = T>
|
|
|
|
+ Debug + Trig + From<i32> + Copy {
|
|
|
|
TMatrix( (1.into(), 0.into(), 0.into(), 0.into())
|
|
|
|
, (0.into(), 1.into(), 0.into(), 0.into())
|
|
|
|
, (0.into(), 0.into(), 1.into(), 0.into())
|
|
|
|
, (0.into(), 0.into(), 0.into(), 1.into()) )
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn translate<T>(v :Vector<T>) -> TMatrix<T>
|
|
|
|
where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
|
|
|
|
+ Mul<Output = T> + Div<Output = T> + Trig + From<i32> + Copy {
|
|
|
|
let Vector(x, y, z) = v;
|
|
|
|
+ Mul<Output = T> + Div<Output = T>
|
|
|
|
+ Debug + Trig + From<i32> + Copy {
|
|
|
|
let Vector(x, y, z) = v;
|
|
|
|
|
|
|
|
TMatrix( (1.into(), 0.into(), 0.into(), 0.into())
|
|
|
|
, (0.into(), 1.into(), 0.into(), 0.into())
|
|
|
|
, (0.into(), 0.into(), 1.into(), 0.into())
|
|
|
|
, ( x, y, z, 1.into()) )
|
|
|
|
TMatrix( (1.into(), 0.into(), 0.into(), x)
|
|
|
|
, (0.into(), 1.into(), 0.into(), y)
|
|
|
|
, (0.into(), 0.into(), 1.into(), z)
|
|
|
|
, (0.into(), 0.into(), 0.into(), 1.into()) )
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn rotate_x<T>(a :i32) -> TMatrix<T>
|
|
|
|
where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
|
|
|
|
+ Mul<Output = T> + Div<Output = T> + Trig + From<i32> + Copy {
|
|
|
|
+ Mul<Output = T> + Div<Output = T>
|
|
|
|
+ Debug + Trig + From<i32> + Copy {
|
|
|
|
let sin :T = Trig::sin(a);
|
|
|
|
let cos :T = Trig::cos(a);
|
|
|
|
|
|
|
|
@ -63,7 +68,8 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> |
|
|
|
|
|
|
|
pub fn rotate_y<T>(a :i32) -> TMatrix<T>
|
|
|
|
where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
|
|
|
|
+ Mul<Output = T> + Div<Output = T> + Trig + From<i32> + Copy {
|
|
|
|
+ Mul<Output = T> + Div<Output = T>
|
|
|
|
+ Debug + Trig + From<i32> + Copy {
|
|
|
|
let sin :T = Trig::sin(a);
|
|
|
|
let cos :T = Trig::cos(a);
|
|
|
|
|
|
|
|
@ -75,7 +81,8 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> |
|
|
|
|
|
|
|
pub fn rotate_z<T>(a :i32) -> TMatrix<T>
|
|
|
|
where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
|
|
|
|
+ Mul<Output = T> + Div<Output = T> + Trig + From<i32> + Copy {
|
|
|
|
+ Mul<Output = T> + Div<Output = T>
|
|
|
|
+ Debug + Trig + From<i32> + Copy {
|
|
|
|
let sin :T = Trig::sin(a);
|
|
|
|
let cos :T = Trig::cos(a);
|
|
|
|
|
|
|
|
@ -87,7 +94,8 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> |
|
|
|
|
|
|
|
pub fn rotate_v<T>(v :&Vector<T>, a :i32) -> TMatrix<T>
|
|
|
|
where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
|
|
|
|
+ Mul<Output = T> + Div<Output = T> + Trig + From<i32> + Copy {
|
|
|
|
+ Mul<Output = T> + Div<Output = T>
|
|
|
|
+ Debug + Trig + From<i32> + Copy {
|
|
|
|
let Vector(x, y, z) = *v;
|
|
|
|
|
|
|
|
let sin :T = Trig::sin(a);
|
|
|
|
@ -113,7 +121,8 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> |
|
|
|
|
|
|
|
pub fn scale<T>(v :Vector<T>) -> TMatrix<T>
|
|
|
|
where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
|
|
|
|
+ Mul<Output = T> + Div<Output = T> + Trig + From<i32> + Copy {
|
|
|
|
+ Mul<Output = T> + Div<Output = T>
|
|
|
|
+ Debug + Trig + From<i32> + Copy {
|
|
|
|
let Vector(x, y, z) = v;
|
|
|
|
|
|
|
|
TMatrix( ( x, 0.into(), 0.into(), 0.into())
|
|
|
|
@ -124,11 +133,19 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> |
|
|
|
|
|
|
|
impl<T> TMatrix<T>
|
|
|
|
where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
|
|
|
|
+ Mul<Output = T> + Div<Output = T> + Trig + From<i32> + Copy {
|
|
|
|
+ Mul<Output = T> + Div<Output = T>
|
|
|
|
+ Debug + Trig + From<i32> + Copy {
|
|
|
|
pub fn new( r1 :(T, T, T, T)
|
|
|
|
, r2 :(T, T, T, T)
|
|
|
|
, r3 :(T, T, T, T)
|
|
|
|
, r4 :(T, T, T, T) ) -> TMatrix<T> {
|
|
|
|
TMatrix(r1, r2, r3, r4)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn combine<I>(mi :I) -> TMatrix<T>
|
|
|
|
where I: IntoIterator<Item = TMatrix<T>> {
|
|
|
|
|
|
|
|
mi.into_iter().fold(unit(), |acc, x| acc * x)
|
|
|
|
mi.into_iter().fold(unit(), |acc, x| x * acc)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn apply(&self, v :&Vector<T>) -> Vector<T> {
|
|
|
|
@ -138,10 +155,10 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> |
|
|
|
, (a41, a42, a43, a44) ) = *self;
|
|
|
|
let Vector(x, y, z) = *v;
|
|
|
|
|
|
|
|
let v = Vector( a11 * x + a21 * y + a31 * z + a41
|
|
|
|
, a12 * x + a22 * y + a32 * z + a42
|
|
|
|
, a13 * x + a23 * y + a33 * z + a43 );
|
|
|
|
let w = a14 * x + a24 * y + a34 * z + a44;
|
|
|
|
let v = Vector( a11 * x + a12 * y + a13 * z + a14
|
|
|
|
, a21 * x + a22 * y + a23 * z + a24
|
|
|
|
, a31 * x + a32 * y + a33 * z + a34 );
|
|
|
|
let w = a41 * x + a42 * y + a43 * z + a44;
|
|
|
|
|
|
|
|
v.mul(&w.recip())
|
|
|
|
}
|
|
|
|
@ -149,7 +166,8 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> |
|
|
|
|
|
|
|
impl<T> Mul for TMatrix<T>
|
|
|
|
where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
|
|
|
|
+ Mul<Output = T> + Div<Output = T> + Trig + From<i32> + Copy {
|
|
|
|
+ Mul<Output = T> + Div<Output = T>
|
|
|
|
+ Debug + Trig + From<i32> + Copy {
|
|
|
|
type Output = Self;
|
|
|
|
|
|
|
|
// ATTENTION: This is not commutative, nor assoziative.
|
|
|
|
|