Browse Source

Add basic geometric transformations

master
Georg Hopp 6 years ago
parent
commit
8274976de6
Signed by: ghopp GPG Key ID: 4C5D226768784538
  1. 3
      fractional/src/lib.rs
  2. 52
      fractional/src/main.rs
  3. 137
      fractional/src/transform.rs

3
fractional/src/lib.rs

@ -23,5 +23,8 @@ extern crate lazy_static;
pub mod fractional; pub mod fractional;
pub mod trigonometry; pub mod trigonometry;
pub mod vector; pub mod vector;
pub mod transform;
use fractional::{Fractional}; use fractional::{Fractional};
use trigonometry::{sin, cos};
use vector::{Vector};

52
fractional/src/main.rs

@ -25,6 +25,7 @@ use std::f64::consts::PI as FPI;
use fractional::fractional::{Fractional, from_vector, Continuous}; use fractional::fractional::{Fractional, from_vector, Continuous};
use fractional::trigonometry::{sin, cos, tan, PI}; use fractional::trigonometry::{sin, cos, tan, PI};
use fractional::vector::{Vector}; use fractional::vector::{Vector};
use fractional::transform::{translate, rotate_x, rotate_y, rotate_z, rotate_v};
fn mean(v: &Vec<i64>) -> Result<Fractional, TryFromIntError> { fn mean(v: &Vec<i64>) -> Result<Fractional, TryFromIntError> {
let r = v.iter().fold(0, |acc, x| acc + x); let r = v.iter().fold(0, |acc, x| acc + x);
@ -148,6 +149,55 @@ fn _vector() {
println!("{:>14} : {}", "v2 * v1", v2 * v1); println!("{:>14} : {}", "v2 * v1", v2 * v1);
} }
fn _transform() {
let v = Vector(1.into(), 1.into(), 1.into());
let v1 = Vector(1.into(), 2.into(), 3.into());
let mt = translate(v);
println!("{:>14} : {}", "Vector v1", v1);
println!("{:>14} : {}", "translate v1", mt.apply(&v1));
println!();
let v2 = Vector(1.into(), 1.into(), 0.into());
println!("{:>14} : {}", "Vector v2", v2);
for d in [ 30, 45, 60, 90, 120, 135, 150, 180
, 210, 225, 240, 270, 300, 315, 330 ].iter() {
let m = rotate_x(*d as i32);
println!("{:>14} : {}", format!("rot_x {} v2", d), m.apply(&v2));
}
println!();
println!("{:>14} : {}", "Vector v2", v2);
for d in [ 30, 45, 60, 90, 120, 135, 150, 180
, 210, 225, 240, 270, 300, 315, 330 ].iter() {
let m = rotate_y(*d as i32);
println!("{:>14} : {}", format!("rot_y {} v2", d), m.apply(&v2));
}
println!();
for d in [ 30, 45, 60, 90, 120, 135, 150, 180
, 210, 225, 240, 270, 300, 315, 330 ].iter() {
let m = rotate_x(*d as i32) * rotate_y(*d as i32);
println!("{:>14} : {}", format!("rot_xy {} v2", d), m.apply(&v2));
}
println!();
let v3 = Vector(1.into(), 0.into(), 1.into());
println!("{:>14} : {}", "Vector v3", v3);
for d in [ 30, 45, 60, 90, 120, 135, 150, 180
, 210, 225, 240, 270, 300, 315, 330 ].iter() {
let m = rotate_z(*d as i32);
println!("{:>14} : {}", format!("rot_z {} v3", d), m.apply(&v3));
}
println!();
for d in [ 30, 45, 60, 90, 120, 135, 150, 180
, 210, 225, 240, 270, 300, 315, 330 ].iter() {
let m = rotate_v(&v, *d as i32);
println!("{:>14} : {}", format!("rot_v {} v2", d), m.apply(&v2));
}
}
fn main() { fn main() {
common_fractional(); common_fractional();
println!(); println!();
@ -164,4 +214,6 @@ fn main() {
_tan(); _tan();
println!(); println!();
_vector(); _vector();
println!();
_transform();
} }

137
fractional/src/transform.rs

@ -0,0 +1,137 @@
//
// Transformation of vectors in a given coordinate system...
//
// Georg Hopp <georg@steffers.org>
//
// Copyright © 2019 Georg Hopp
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
use std::ops::{Mul};
use crate::{Fractional, cos, sin, Vector};
pub struct TMatrix( (Fractional, Fractional, Fractional, Fractional)
, (Fractional, Fractional, Fractional, Fractional)
, (Fractional, Fractional, Fractional, Fractional)
, (Fractional, Fractional, Fractional, Fractional) );
pub fn translate(v :Vector) -> TMatrix {
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()) )
}
pub fn rotate_x(a :i32) -> TMatrix {
TMatrix( (1.into(), 0.into(), 0.into(), 0.into())
, (0.into(), cos(a), -sin(a), 0.into())
, (0.into(), sin(a), cos(a), 0.into())
, (0.into(), 0.into(), 0.into(), 1.into()) )
}
pub fn rotate_y(a :i32) -> TMatrix {
TMatrix( ( cos(a), 0.into(), sin(a), 0.into())
, (0.into(), 1.into(), 0.into(), 0.into())
, ( -sin(a), 0.into(), cos(a), 0.into())
, (0.into(), 0.into(), 0.into(), 1.into()) )
}
pub fn rotate_z(a :i32) -> TMatrix {
TMatrix( ( cos(a), -sin(a), 0.into(), 0.into())
, ( sin(a), cos(a), 0.into(), 0.into())
, (0.into(), 0.into(), 1.into(), 0.into())
, (0.into(), 0.into(), 0.into(), 1.into()) )
}
pub fn rotate_v(v :&Vector, a :i32) -> TMatrix {
let Vector(x, y, z) = *v;
let zero :Fractional = 0.into();
let one :Fractional = 1.into();
TMatrix( ( (one - cos(a)) * x * x + cos(a)
, (one - cos(a)) * x * y - sin(a) * z
, (one - cos(a)) * x * z + sin(a) * y
, zero )
, ( (one - cos(a)) * x * y + sin(a) * z
, (one - cos(a)) * y * y + cos(a)
, (one - cos(a)) * y * z - sin(a) * x
, zero )
, ( (one - cos(a)) * x * z - sin(a) * y
, (one - cos(a)) * y * z + sin(a) * x
, (one - cos(a)) * z * z + cos(a)
, zero )
, (0.into(), 0.into(), 0.into(), 1.into()) )
}
pub fn scale(v :Vector) -> TMatrix {
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()) )
}
impl TMatrix {
pub fn apply(&self, v :&Vector) -> Vector {
let TMatrix( (a11, a12, a13, a14)
, (a21, a22, a23, a24)
, (a31, a32, a33, a34)
, (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 Fractional(wn, wd) = a14 * x + a24 * y + a34 * z + a44;
v.mul(&Fractional(wd, wn))
}
}
impl Mul for TMatrix {
type Output = Self;
// ATTENTION: This is not commutative, nor assoziative.
fn mul(self, other :Self) -> Self {
let TMatrix( (a11, a12, a13, a14)
, (a21, a22, a23, a24)
, (a31, a32, a33, a34)
, (a41, a42, a43, a44) ) = self;
let TMatrix( (b11, b12, b13, b14)
, (b21, b22, b23, b24)
, (b31, b32, b33, b34)
, (b41, b42, b43, b44) ) = other;
TMatrix( ( a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41
, a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42
, a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43
, a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44 )
, ( a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41
, a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42
, a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43
, a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44 )
, ( a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41
, a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42
, a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43
, a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44 )
, ( a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41
, a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42
, a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43
, a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44 ) )
}
}
Loading…
Cancel
Save