|
|
|
@ -31,121 +31,100 @@ pub struct TMatrix<T>( (T, T, T, T) |
|
|
|
, (T, T, T, T) )
|
|
|
|
where T: Add + Sub + Neg + Mul + Div + Debug + Trig + From<i32> + Copy;
|
|
|
|
|
|
|
|
pub fn unit<T>() -> TMatrix<T>
|
|
|
|
impl<T> TMatrix<T>
|
|
|
|
where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
|
|
|
|
+ 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 new( r1 :(T, T, T, T)
|
|
|
|
, r2 :(T, T, T, T)
|
|
|
|
, r3 :(T, T, T, T)
|
|
|
|
, r4 :(T, T, T, T) ) -> Self {
|
|
|
|
TMatrix(r1, r2, r3, r4)
|
|
|
|
}
|
|
|
|
|
|
|
|
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>
|
|
|
|
+ Debug + Trig + From<i32> + Copy {
|
|
|
|
let Vector(x, y, z) = v;
|
|
|
|
pub fn unit() -> Self {
|
|
|
|
Self::new( (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()) )
|
|
|
|
}
|
|
|
|
|
|
|
|
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 translate(v :Vector<T>) -> Self {
|
|
|
|
let Vector(x, y, z) = v;
|
|
|
|
|
|
|
|
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>
|
|
|
|
+ Debug + Trig + From<i32> + Copy {
|
|
|
|
let sin :T = Trig::sin(a);
|
|
|
|
let cos :T = Trig::cos(a);
|
|
|
|
Self::new( (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()) )
|
|
|
|
}
|
|
|
|
|
|
|
|
TMatrix( (1.into(), 0.into(), 0.into(), 0.into())
|
|
|
|
, (0.into(), cos , -sin , 0.into())
|
|
|
|
, (0.into(), sin , cos , 0.into())
|
|
|
|
, (0.into(), 0.into(), 0.into(), 1.into()) )
|
|
|
|
}
|
|
|
|
pub fn rotate_x(a :i32) -> Self {
|
|
|
|
let sin :T = Trig::sin(a);
|
|
|
|
let cos :T = Trig::cos(a);
|
|
|
|
|
|
|
|
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>
|
|
|
|
+ Debug + Trig + From<i32> + Copy {
|
|
|
|
let sin :T = Trig::sin(a);
|
|
|
|
let cos :T = Trig::cos(a);
|
|
|
|
Self::new( (1.into(), 0.into(), 0.into(), 0.into())
|
|
|
|
, (0.into(), cos , -sin , 0.into())
|
|
|
|
, (0.into(), sin , cos , 0.into())
|
|
|
|
, (0.into(), 0.into(), 0.into(), 1.into()) )
|
|
|
|
}
|
|
|
|
|
|
|
|
TMatrix( (cos , 0.into(), sin , 0.into())
|
|
|
|
, (0.into(), 1.into(), 0.into(), 0.into())
|
|
|
|
, (-sin , 0.into(), cos , 0.into())
|
|
|
|
, (0.into(), 0.into(), 0.into(), 1.into()) )
|
|
|
|
}
|
|
|
|
pub fn rotate_y(a :i32) -> Self {
|
|
|
|
let sin :T = Trig::sin(a);
|
|
|
|
let cos :T = Trig::cos(a);
|
|
|
|
|
|
|
|
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>
|
|
|
|
+ Debug + Trig + From<i32> + Copy {
|
|
|
|
let sin :T = Trig::sin(a);
|
|
|
|
let cos :T = Trig::cos(a);
|
|
|
|
Self::new( (cos , 0.into(), sin , 0.into())
|
|
|
|
, (0.into(), 1.into(), 0.into(), 0.into())
|
|
|
|
, (-sin , 0.into(), cos , 0.into())
|
|
|
|
, (0.into(), 0.into(), 0.into(), 1.into()) )
|
|
|
|
}
|
|
|
|
|
|
|
|
TMatrix( (cos , -sin , 0.into(), 0.into())
|
|
|
|
, (sin , cos , 0.into(), 0.into())
|
|
|
|
, (0.into(), 0.into(), 1.into(), 0.into())
|
|
|
|
, (0.into(), 0.into(), 0.into(), 1.into()) )
|
|
|
|
}
|
|
|
|
pub fn rotate_z(a :i32) -> Self {
|
|
|
|
let sin :T = Trig::sin(a);
|
|
|
|
let cos :T = Trig::cos(a);
|
|
|
|
|
|
|
|
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>
|
|
|
|
+ Debug + Trig + From<i32> + Copy {
|
|
|
|
let Vector(x, y, z) = *v;
|
|
|
|
|
|
|
|
let sin :T = Trig::sin(a);
|
|
|
|
let cos :T = Trig::cos(a);
|
|
|
|
|
|
|
|
let zero :T = 0.into();
|
|
|
|
let one :T = 1.into();
|
|
|
|
|
|
|
|
TMatrix( ( (one - cos) * x * x + cos
|
|
|
|
, (one - cos) * x * y - sin * z
|
|
|
|
, (one - cos) * x * z + sin * y
|
|
|
|
, zero )
|
|
|
|
, ( (one - cos) * x * y + sin * z
|
|
|
|
, (one - cos) * y * y + cos
|
|
|
|
, (one - cos) * y * z - sin * x
|
|
|
|
, zero )
|
|
|
|
, ( (one - cos) * x * z - sin * y
|
|
|
|
, (one - cos) * y * z + sin * x
|
|
|
|
, (one - cos) * z * z + cos
|
|
|
|
, zero )
|
|
|
|
, (0.into(), 0.into(), 0.into(), 1.into()) )
|
|
|
|
}
|
|
|
|
Self::new( (cos , -sin , 0.into(), 0.into())
|
|
|
|
, (sin , cos , 0.into(), 0.into())
|
|
|
|
, (0.into(), 0.into(), 1.into(), 0.into())
|
|
|
|
, (0.into(), 0.into(), 0.into(), 1.into()) )
|
|
|
|
}
|
|
|
|
|
|
|
|
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>
|
|
|
|
+ Debug + Trig + From<i32> + Copy {
|
|
|
|
let Vector(x, y, z) = v;
|
|
|
|
pub fn rotate_v(v :&Vector<T>, a :i32) -> Self {
|
|
|
|
let Vector(x, y, z) = *v;
|
|
|
|
|
|
|
|
TMatrix( ( x, 0.into(), 0.into(), 0.into())
|
|
|
|
, (0.into(), y, 0.into(), 0.into())
|
|
|
|
, (0.into(), 0.into(), z, 0.into())
|
|
|
|
, (0.into(), 0.into(), 0.into(), 1.into()) )
|
|
|
|
}
|
|
|
|
let sin :T = Trig::sin(a);
|
|
|
|
let cos :T = Trig::cos(a);
|
|
|
|
|
|
|
|
let zero :T = 0.into();
|
|
|
|
let one :T = 1.into();
|
|
|
|
|
|
|
|
Self::new( ( (one - cos) * x * x + cos
|
|
|
|
, (one - cos) * x * y - sin * z
|
|
|
|
, (one - cos) * x * z + sin * y
|
|
|
|
, zero )
|
|
|
|
, ( (one - cos) * x * y + sin * z
|
|
|
|
, (one - cos) * y * y + cos
|
|
|
|
, (one - cos) * y * z - sin * x
|
|
|
|
, zero )
|
|
|
|
, ( (one - cos) * x * z - sin * y
|
|
|
|
, (one - cos) * y * z + sin * x
|
|
|
|
, (one - cos) * z * z + cos
|
|
|
|
, zero )
|
|
|
|
, (0.into(), 0.into(), 0.into(), 1.into()) )
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> TMatrix<T>
|
|
|
|
where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
|
|
|
|
+ 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 scale(v :Vector<T>) -> Self {
|
|
|
|
let Vector(x, y, z) = v;
|
|
|
|
|
|
|
|
Self::new( ( x, 0.into(), 0.into(), 0.into())
|
|
|
|
, (0.into(), y, 0.into(), 0.into())
|
|
|
|
, (0.into(), 0.into(), z, 0.into())
|
|
|
|
, (0.into(), 0.into(), 0.into(), 1.into()) )
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn combine<I>(mi :I) -> TMatrix<T>
|
|
|
|
where I: IntoIterator<Item = TMatrix<T>> {
|
|
|
|
|
|
|
|
mi.into_iter().fold(unit(), |acc, x| x * acc)
|
|
|
|
mi.into_iter().fold(Self::unit(), |acc, x| x * acc)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn apply(&self, v :&Vector<T>) -> Vector<T> {
|
|
|
|
|