Commit 9911ab0166cd4abf0e50252234b5dba8b1360b9b

Authored by Georg Hopp
1 parent 6fd0ac65

Add homogenous point.

A homogenous point, that is (x, y, z, w) is needed for some
transdormations and calculations. Right now i need it to get
correct 1/z values after 2D projection which in turn will be
needed for z-buffer and texture mapping.
@@ -18,12 +18,12 @@ @@ -18,12 +18,12 @@
18 // You should have received a copy of the GNU General Public License 18 // You should have received a copy of the GNU General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>. 19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 // 20 //
21 -use std::convert::From; 21 +use std::convert::{From, Into};
22 use std::ops::{Add,Sub,Neg,Mul,Div}; 22 use std::ops::{Add,Sub,Neg,Mul,Div};
23 use std::fmt::Debug; 23 use std::fmt::Debug;
24 24
25 use crate::easel::{Canvas,Coordinate,Coordinates,Polygon}; 25 use crate::easel::{Canvas,Coordinate,Coordinates,Polygon};
26 -use crate::transform::TMatrix; 26 +use crate::transform::{TMatrix, Transformable};
27 use crate::trigonometry::Trig; 27 use crate::trigonometry::Trig;
28 use crate::vector::Vector; 28 use crate::vector::Vector;
29 29
@@ -34,10 +34,113 @@ where T: Add + Sub + Neg + Mul + Div + Copy + Trig { @@ -34,10 +34,113 @@ where T: Add + Sub + Neg + Mul + Div + Copy + Trig {
34 normal :Option<Vector<T>>, 34 normal :Option<Vector<T>>,
35 } 35 }
36 36
  37 +#[derive(Debug, PartialEq, Eq, Clone, Copy)]
  38 +pub struct Point<T>(pub Vector<T>, T)
  39 + where T: Add + Sub + Neg + Mul + Div + PartialEq + Copy + Trig;
  40 +
  41 +impl<T> Point<T>
  42 +where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
  43 + + Mul<Output = T> + Div<Output = T>
  44 + + PartialEq + Trig + Copy + From<i32> {
  45 + pub fn new(x :T, y :T, z :T) -> Self {
  46 + Self(Vector(x, y, z), 1.into())
  47 + }
  48 +}
  49 +
  50 +impl<T> Add for Point<T>
  51 +where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
  52 + + Mul<Output = T> + Div<Output = T>
  53 + + PartialEq + Trig + Copy {
  54 + type Output = Self;
  55 +
  56 + fn add(self, other :Self) -> Self {
  57 + let Point(v1, w1) = self;
  58 + let Point(v2, w2) = other;
  59 + Self(v1 + v2, w1 + w2)
  60 + }
  61 +}
  62 +
  63 +impl<T> Neg for Point<T>
  64 +where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
  65 + + Mul<Output = T> + Div<Output = T>
  66 + + PartialEq + Trig + Copy {
  67 + type Output = Self;
  68 +
  69 + fn neg(self) -> Self {
  70 + let Point(v, w) = self;
  71 + Self(-v, -w)
  72 + }
  73 +}
  74 +
  75 +impl<T> Sub for Point<T>
  76 +where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
  77 + + Mul<Output = T> + Div<Output = T>
  78 + + PartialEq + Trig + Copy {
  79 + type Output = Self;
  80 +
  81 + fn sub(self, other :Self) -> Self {
  82 + self + -other
  83 + }
  84 +}
  85 +
  86 +impl<T> Mul for Point<T>
  87 +where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
  88 + + Mul<Output = T> + Div<Output = T>
  89 + + PartialEq + Trig + Copy + From<i32> {
  90 + type Output = Self;
  91 +
  92 + fn mul(self, other :Self) -> Self {
  93 + let a :Vector<T> = self.into();
  94 + let b :Vector<T> = other.into();
  95 +
  96 + Point(a * b, 1.into())
  97 + }
  98 +}
  99 +
  100 +impl<T> From<Vector<T>> for Point<T>
  101 +where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
  102 + + Mul<Output = T> + Div<Output = T>
  103 + + PartialEq + Trig + Copy + From<i32> {
  104 + fn from(v :Vector<T>) -> Self {
  105 + Point(v, 1.into())
  106 + }
  107 +}
  108 +
  109 +impl<T> Into<Vector<T>> for Point<T>
  110 +where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
  111 + + Mul<Output = T> + Div<Output = T>
  112 + + PartialEq + Trig + Copy + From<i32> {
  113 + fn into(self) -> Vector<T> {
  114 + let Point(v, w) = self;
  115 +
  116 + if w == 0.into() {
  117 + v
  118 + } else {
  119 + v.mul(&w.recip())
  120 + }
  121 + }
  122 +}
  123 +
  124 +impl<T> Transformable<T> for Point<T>
  125 +where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
  126 + + Mul<Output = T> + Div<Output = T>
  127 + + PartialEq + Debug + Trig + Copy + From<i32> {
  128 + fn transform(&self, m :&TMatrix<T>) -> Self {
  129 + let Point(v, w) = *self;
  130 + let (v, w) = m.apply(&v, w);
  131 +
  132 + if w == 0.into() {
  133 + v.into()
  134 + } else {
  135 + v.mul(&w.recip()).into()
  136 + }
  137 + }
  138 +}
  139 +
37 #[derive(Debug)] 140 #[derive(Debug)]
38 pub struct Polyeder<T> 141 pub struct Polyeder<T>
39 -where T: Add + Sub + Neg + Mul + Div + Copy + Trig {  
40 - points :Vec<Vector<T>>, 142 +where T: Add + Sub + Neg + Mul + Div + PartialEq + Copy + Trig {
  143 + points :Vec<Point<T>>,
41 faces :Vec<Face<T>>, 144 faces :Vec<Face<T>>,
42 } 145 }
43 146
@@ -65,7 +168,7 @@ where T: Add + Sub + Neg + Mul + Div + Debug + Copy + Trig + From<i32> { @@ -65,7 +168,7 @@ where T: Add + Sub + Neg + Mul + Div + Debug + Copy + Trig + From<i32> {
65 impl<T> Camera<T> 168 impl<T> Camera<T>
66 where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> 169 where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
67 + Mul<Output = T> + Div<Output = T> 170 + Mul<Output = T> + Div<Output = T>
68 - + Debug + Copy + Trig + From<i32> { 171 + + PartialEq + Debug + Copy + Trig + From<i32> {
69 // This code assumes that the size of the viewport is always 172 // This code assumes that the size of the viewport is always
70 // equal to the size of the physical screen… e.g. window/canvas thus some 173 // equal to the size of the physical screen… e.g. window/canvas thus some
71 // effects can't be done. See book for examples with different viewport 174 // effects can't be done. See book for examples with different viewport
@@ -91,9 +194,9 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> @@ -91,9 +194,9 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
91 self.project 194 self.project
92 } 195 }
93 196
94 - pub fn project(&self, v :Vector<T>) -> Coordinate {  
95 - let p = self.project.apply(&v);  
96 - Coordinate(T::round(&p.x()), T::round(&p.y())) 197 + pub fn project(&self, p :Point<T>) -> Coordinate {
  198 + let Point(v, _) = p.transform(&self.project);
  199 + Coordinate(T::round(&v.x()), T::round(&v.y()))
97 } 200 }
98 } 201 }
99 202
@@ -113,16 +216,16 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> @@ -113,16 +216,16 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
113 impl<T> Face<T> 216 impl<T> Face<T>
114 where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> 217 where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
115 + Mul<Output = T> + Div<Output = T> 218 + Mul<Output = T> + Div<Output = T>
116 - + Debug + Copy + Trig + From<i32> {  
117 - fn new(corners :Vec<usize>, ps :&[Vector<T>]) -> Self { 219 + + PartialEq + Debug + Copy + Trig + From<i32> {
  220 + fn new(corners :Vec<usize>, ps :&[Point<T>]) -> Self {
118 let mut f = Face{ corners: corners, normal: None }; 221 let mut f = Face{ corners: corners, normal: None };
119 f.update_normal(ps); 222 f.update_normal(ps);
120 f 223 f
121 } 224 }
122 225
123 - fn update_normal(&mut self, ps :&[Vector<T>]) {  
124 - let edge10 = ps[self.corners[1]] - ps[self.corners[0]];  
125 - let edge12 = ps[self.corners[1]] - ps[self.corners[2]]; 226 + fn update_normal(&mut self, ps :&[Point<T>]) {
  227 + let edge10 :Vector<T> = (ps[self.corners[1]] - ps[self.corners[0]]).into();
  228 + let edge12 :Vector<T> = (ps[self.corners[1]] - ps[self.corners[2]]).into();
126 self.normal = Some(edge10 * edge12); 229 self.normal = Some(edge10 * edge12);
127 } 230 }
128 } 231 }
@@ -130,7 +233,7 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> @@ -130,7 +233,7 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
130 impl<T> Polyeder<T> 233 impl<T> Polyeder<T>
131 where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> 234 where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
132 + Mul<Output = T> + Div<Output = T> 235 + Mul<Output = T> + Div<Output = T>
133 - + Debug + Copy + Trig + From<i32> { 236 + + PartialEq + Debug + Copy + Trig + From<i32> {
134 fn update_normals(&mut self) { 237 fn update_normals(&mut self) {
135 for f in self.faces.iter_mut() { 238 for f in self.faces.iter_mut() {
136 f.update_normal(&self.points); 239 f.update_normal(&self.points);
@@ -156,10 +259,10 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> @@ -156,10 +259,10 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
156 // half the deeps in z 259 // half the deeps in z
157 let _zh :T = T::sqrt(f3).unwrap() / f4 * a; 260 let _zh :T = T::sqrt(f3).unwrap() / f4 * a;
158 261
159 - let ps = vec!( Vector( f0, yc, f0)  
160 - , Vector(-ah, -yi, -zi)  
161 - , Vector( ah, -yi, -zi)  
162 - , Vector( f0, -yi, zc) ); 262 + let ps = vec!( Point::new( f0, yc, f0)
  263 + , Point::new(-ah, -yi, -zi)
  264 + , Point::new( ah, -yi, -zi)
  265 + , Point::new( f0, -yi, zc) );
163 266
164 let fs = vec!( Face::new(vec!(1, 2, 3), &ps) 267 let fs = vec!( Face::new(vec!(1, 2, 3), &ps)
165 , Face::new(vec!(1, 0, 2), &ps) 268 , Face::new(vec!(1, 0, 2), &ps)
@@ -177,9 +280,9 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> @@ -177,9 +280,9 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
177 let zc :T = T::sqrt(f3).unwrap() / f3 * a; 280 let zc :T = T::sqrt(f3).unwrap() / f3 * a;
178 let ah :T = a / 2.into(); 281 let ah :T = a / 2.into();
179 282
180 - let ps = vec!( Vector(-ah, f0, -zi)  
181 - , Vector( f0, f0, zc)  
182 - , Vector( ah, f0, -zi) ); 283 + let ps = vec!( Point::new(-ah, f0, -zi)
  284 + , Point::new( f0, f0, zc)
  285 + , Point::new( ah, f0, -zi) );
183 286
184 let fs = vec!(Face::new(vec!(0, 1, 2), &ps)); 287 let fs = vec!(Face::new(vec!(0, 1, 2), &ps));
185 288
@@ -191,14 +294,14 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> @@ -191,14 +294,14 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
191 pub fn cube(a :T) -> Polyeder<T> { 294 pub fn cube(a :T) -> Polyeder<T> {
192 let ah :T = a / From::<i32>::from(2); 295 let ah :T = a / From::<i32>::from(2);
193 296
194 - let ps = vec!( Vector(-ah, ah, -ah) // 0 => front 1  
195 - , Vector(-ah, -ah, -ah) // 1 => front 2  
196 - , Vector( ah, -ah, -ah) // 2 => front 3  
197 - , Vector( ah, ah, -ah) // 3 => front 4  
198 - , Vector(-ah, ah, ah) // 4 => back 1  
199 - , Vector(-ah, -ah, ah) // 5 => back 2  
200 - , Vector( ah, -ah, ah) // 6 => back 3  
201 - , Vector( ah, ah, ah) ); // 7 => back 4 297 + let ps = vec!( Point::new(-ah, ah, -ah) // 0 => front 1
  298 + , Point::new(-ah, -ah, -ah) // 1 => front 2
  299 + , Point::new( ah, -ah, -ah) // 2 => front 3
  300 + , Point::new( ah, ah, -ah) // 3 => front 4
  301 + , Point::new(-ah, ah, ah) // 4 => back 1
  302 + , Point::new(-ah, -ah, ah) // 5 => back 2
  303 + , Point::new( ah, -ah, ah) // 6 => back 3
  304 + , Point::new( ah, ah, ah) ); // 7 => back 4
202 305
203 let fs = vec!( Face::new(vec!(0, 1, 2, 3), &ps) // front 306 let fs = vec!( Face::new(vec!(0, 1, 2, 3), &ps) // front
204 , Face::new(vec!(7, 6, 5, 4), &ps) // back 307 , Face::new(vec!(7, 6, 5, 4), &ps) // back
@@ -218,8 +321,10 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> @@ -218,8 +321,10 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
218 fn transform(&self, m :&TMatrix<T>) -> Self { 321 fn transform(&self, m :&TMatrix<T>) -> Self {
219 let Polyeder{ points: ps, faces: fs } = self; 322 let Polyeder{ points: ps, faces: fs } = self;
220 323
221 - let mut p = Polyeder{ points: ps.iter().map(|p| m.apply(p)).collect()  
222 - , faces: fs.to_vec() }; 324 + let mut p = Polyeder{
  325 + points: ps.iter().map(|p| p.transform(m)).collect()
  326 + , faces: fs.to_vec()
  327 + };
223 328
224 // TODO alternatively we could rotate the normals too, but this cannot 329 // TODO alternatively we could rotate the normals too, but this cannot
225 // done with the original matrix… the question is, what is faster. 330 // done with the original matrix… the question is, what is faster.
@@ -34,7 +34,7 @@ use fractional::easel::{ Coordinate, Coordinates, Drawable, Line, Polyline @@ -34,7 +34,7 @@ use fractional::easel::{ Coordinate, Coordinates, Drawable, Line, Polyline
34 use fractional::fractional::{Fractional, from_vector}; 34 use fractional::fractional::{Fractional, from_vector};
35 use fractional::trigonometry::Trig; 35 use fractional::trigonometry::Trig;
36 use fractional::vector::Vector; 36 use fractional::vector::Vector;
37 -use fractional::transform::TMatrix; 37 +use fractional::transform::{TMatrix, Transformable};
38 38
39 use fractional::xcb::XcbEasel; 39 use fractional::xcb::XcbEasel;
40 use fractional::easel::Canvas; 40 use fractional::easel::Canvas;
@@ -204,7 +204,8 @@ fn _transform<T>(v :Vector<T>, v1 :Vector<T>, v2 :Vector<T>, v3 :Vector<T>) @@ -204,7 +204,8 @@ fn _transform<T>(v :Vector<T>, v1 :Vector<T>, v2 :Vector<T>, v3 :Vector<T>)
204 + Debug + From<i32> + Copy + Display { 204 + Debug + From<i32> + Copy + Display {
205 205
206 println!("{:>14} : {}", "Vector v1", v1); 206 println!("{:>14} : {}", "Vector v1", v1);
207 - println!("{:>14} : {}", "translate v1", TMatrix::translate(v).apply(&v1)); 207 + println!( "{:>14} : {}", "translate v1"
  208 + , v.transform(&TMatrix::translate(v)));
208 println!(); 209 println!();
209 210
210 fn _rot<T>( o :&str , n :&str , v :&Vector<T> 211 fn _rot<T>( o :&str , n :&str , v :&Vector<T>
@@ -218,7 +219,7 @@ fn _transform<T>(v :Vector<T>, v1 :Vector<T>, v2 :Vector<T>, v3 :Vector<T>) @@ -218,7 +219,7 @@ fn _transform<T>(v :Vector<T>, v1 :Vector<T>, v2 :Vector<T>, v3 :Vector<T>)
218 let mi = fs.iter().map(|f| f(*d as i32)); 219 let mi = fs.iter().map(|f| f(*d as i32));
219 println!( "{:>14} : {}" 220 println!( "{:>14} : {}"
220 , format!("{} {} {}", o, d, n) 221 , format!("{} {} {}", o, d, n)
221 - , TMatrix::combine(mi).apply(v) ); 222 + , v.transform(&TMatrix::combine(mi)) );
222 } 223 }
223 } 224 }
224 225
@@ -237,7 +238,7 @@ fn _transform<T>(v :Vector<T>, v1 :Vector<T>, v2 :Vector<T>, v3 :Vector<T>) @@ -237,7 +238,7 @@ fn _transform<T>(v :Vector<T>, v1 :Vector<T>, v2 :Vector<T>, v3 :Vector<T>)
237 , 210, 225, 240, 270, 300, 315, 330 ].iter() { 238 , 210, 225, 240, 270, 300, 315, 330 ].iter() {
238 println!( "{:>14} : {}" 239 println!( "{:>14} : {}"
239 , format!("rot_v {} v2", d) 240 , format!("rot_v {} v2", d)
240 - , TMatrix::rotate_v(&v, *d as i32).apply(&v2)); 241 + , v2.transform(&TMatrix::rotate_v(&v, *d as i32)) );
241 } 242 }
242 } 243 }
243 244
@@ -273,9 +274,9 @@ fn _line() { @@ -273,9 +274,9 @@ fn _line() {
273 let k = Vector(Fractional(-30,1), Fractional( 30,1), Fractional(0,1)); 274 let k = Vector(Fractional(-30,1), Fractional( 30,1), Fractional(0,1));
274 275
275 let rot :TMatrix<Fractional> = TMatrix::rotate_z(20); 276 let rot :TMatrix<Fractional> = TMatrix::rotate_z(20);
276 - let Vector(ix, iy, _) = rot.apply(&i);  
277 - let Vector(jx, jy, _) = rot.apply(&j);  
278 - let Vector(kx, ky, _) = rot.apply(&k); 277 + let Vector(ix, iy, _) = i.transform(&rot);
  278 + let Vector(jx, jy, _) = j.transform(&rot);
  279 + let Vector(kx, ky, _) = k.transform(&rot);
279 280
280 fn to_i32(x :Fractional) -> i32 { 281 fn to_i32(x :Fractional) -> i32 {
281 let Fractional(n, d) = x; 282 let Fractional(n, d) = x;
@@ -294,9 +295,9 @@ fn _line() { @@ -294,9 +295,9 @@ fn _line() {
294 let k = Vector(-30.0, 30.0, 0.0); 295 let k = Vector(-30.0, 30.0, 0.0);
295 296
296 let rot :TMatrix<f64> = TMatrix::rotate_z(20); 297 let rot :TMatrix<f64> = TMatrix::rotate_z(20);
297 - let Vector(ix, iy, _) = rot.apply(&i);  
298 - let Vector(jx, jy, _) = rot.apply(&j);  
299 - let Vector(kx, ky, _) = rot.apply(&k); 298 + let Vector(ix, iy, _) = i.transform(&rot);
  299 + let Vector(jx, jy, _) = j.transform(&rot);
  300 + let Vector(kx, ky, _) = k.transform(&rot);
300 301
301 fn to_i32_2(x :f64) -> i32 { 302 fn to_i32_2(x :f64) -> i32 {
302 x.round() as i32 303 x.round() as i32
@@ -334,24 +335,15 @@ fn _democanvas<T>( xcb :&XcbEasel @@ -334,24 +335,15 @@ fn _democanvas<T>( xcb :&XcbEasel
334 let step = Duration::from_millis(25); 335 let step = Duration::from_millis(25);
335 let mut last = Instant::now(); 336 let mut last = Instant::now();
336 337
337 - let t :TMatrix<T> = TMatrix::translate(Vector( 0.into()  
338 - , 0.into()  
339 - , 150.into() ));  
340 - // We do not need this here… it is used within projection…  
341 - // let p :TMatrix<T> = camera.get_projection(); 338 + let t = TMatrix::translate(Vector(0.into() , 0.into() , 150.into()));
342 339
343 loop { 340 loop {
344 let deg = ((start.elapsed() / 25).as_millis() % 360) as i32; 341 let deg = ((start.elapsed() / 25).as_millis() % 360) as i32;
345 342
346 - let rz :TMatrix<T> = TMatrix::rotate_z(deg);  
347 - let rx :TMatrix<T> = TMatrix::rotate_x(-deg*2);  
348 - let ry :TMatrix<T> = TMatrix::rotate_y(-deg*2); 343 + let rz = TMatrix::rotate_z(deg);
  344 + let rx = TMatrix::rotate_x(-deg*2);
  345 + let ry = TMatrix::rotate_y(-deg*2);
349 346
350 - // I can not apply the projection in one turn, as I generate the  
351 - // normals always… and this is no longer possible after the  
352 - // projection…  
353 - // let rot1 = TMatrix::combine(vec!(rz, rx, t, p));  
354 - // let rot2 = TMatrix::combine(vec!(rz, ry, t, p));  
355 let rot1 = TMatrix::combine(vec!(rz, rx, t)); 347 let rot1 = TMatrix::combine(vec!(rz, rx, t));
356 let rot2 = TMatrix::combine(vec!(rz, ry, t)); 348 let rot2 = TMatrix::combine(vec!(rz, ry, t));
357 349
@@ -31,6 +31,11 @@ pub struct TMatrix<T>( (T, T, T, T) @@ -31,6 +31,11 @@ pub struct TMatrix<T>( (T, T, T, T)
31 , (T, T, T, T) ) 31 , (T, T, T, T) )
32 where T: Add + Sub + Neg + Mul + Div + Debug + Trig + From<i32> + Copy; 32 where T: Add + Sub + Neg + Mul + Div + Debug + Trig + From<i32> + Copy;
33 33
  34 +pub trait Transformable<T>
  35 +where T: Add + Sub + Neg + Mul + Div + Debug + Trig + From<i32> + Copy {
  36 + fn transform(&self, m :&TMatrix<T>) -> Self;
  37 +}
  38 +
34 impl<T> TMatrix<T> 39 impl<T> TMatrix<T>
35 where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> 40 where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
36 + Mul<Output = T> + Div<Output = T> 41 + Mul<Output = T> + Div<Output = T>
@@ -127,19 +132,20 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> @@ -127,19 +132,20 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
127 mi.into_iter().fold(Self::unit(), |acc, x| x * acc) 132 mi.into_iter().fold(Self::unit(), |acc, x| x * acc)
128 } 133 }
129 134
130 - pub fn apply(&self, v :&Vector<T>) -> Vector<T> { 135 + pub fn apply(&self, v :&Vector<T>, w :T) -> (Vector<T>, T) {
131 let TMatrix( (a11, a12, a13, a14) 136 let TMatrix( (a11, a12, a13, a14)
132 , (a21, a22, a23, a24) 137 , (a21, a22, a23, a24)
133 , (a31, a32, a33, a34) 138 , (a31, a32, a33, a34)
134 , (a41, a42, a43, a44) ) = *self; 139 , (a41, a42, a43, a44) ) = *self;
135 let Vector(x, y, z) = *v; 140 let Vector(x, y, z) = *v;
136 141
137 - let v = Vector( a11 * x + a12 * y + a13 * z + a14  
138 - , a21 * x + a22 * y + a23 * z + a24  
139 - , a31 * x + a32 * y + a33 * z + a34 );  
140 - let w = a41 * x + a42 * y + a43 * z + a44; 142 + let v = Vector( a11 * x + a12 * y + a13 * z + a14 * w
  143 + , a21 * x + a22 * y + a23 * z + a24 * w
  144 + , a31 * x + a32 * y + a33 * z + a34 * w );
  145 + let w = a41 * x + a42 * y + a43 * z + a44 * w;
141 146
142 - v.mul(&w.recip()) 147 + //v.mul(&w.recip())
  148 + (v, w)
143 } 149 }
144 } 150 }
145 151
@@ -18,10 +18,11 @@ @@ -18,10 +18,11 @@
18 // You should have received a copy of the GNU General Public License 18 // You should have received a copy of the GNU General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>. 19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 // 20 //
21 -use std::fmt::{Formatter, Display, Result}; 21 +use std::fmt::{Debug, Display, Formatter, Result};
22 use std::ops::{Add, Sub, Neg, Mul, Div}; 22 use std::ops::{Add, Sub, Neg, Mul, Div};
23 23
24 use crate::trigonometry::Trig; 24 use crate::trigonometry::Trig;
  25 +use crate::transform::{TMatrix, Transformable};
25 26
26 #[derive(Debug, Eq, Clone, Copy)] 27 #[derive(Debug, Eq, Clone, Copy)]
27 pub struct Vector<T>(pub T, pub T, pub T) 28 pub struct Vector<T>(pub T, pub T, pub T)
@@ -126,3 +127,13 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> @@ -126,3 +127,13 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
126 , ax * by - ay * bx ) 127 , ax * by - ay * bx )
127 } 128 }
128 } 129 }
  130 +
  131 +impl<T> Transformable<T> for Vector<T>
  132 +where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
  133 + + Mul<Output = T> + Div<Output = T>
  134 + + Trig + Copy + Debug + From<i32> {
  135 + fn transform(&self, m :&TMatrix<T>) -> Self {
  136 + let (v, _) = m.apply(self, 0.into());
  137 + v
  138 + }
  139 +}
Please register or login to post a comment