Commit b2f9d492c13cbedae9229096d9ca703225cf3fe8

Authored by Georg Hopp
1 parent fb45f6cc

first very simple shading

Add a very simple shader with a direct light source. The shader
modifies the color of a polygon just by the angle between the face
normal and the light source. This has no physical resemblance at
all but let me check if the normal calculation works so far...
  1 +https://www.themathpage.com/Alg/reciprocals.htm
@@ -11,3 +11,5 @@ http://www.lysator.liu.se/~mikaelk/doc/perspectivetexture/ @@ -11,3 +11,5 @@ http://www.lysator.liu.se/~mikaelk/doc/perspectivetexture/
11 11
12 # Shader... This also describes z-Buffer... :) 12 # Shader... This also describes z-Buffer... :)
13 https://people.ece.cornell.edu/land/OldStudentProjects/cs490-95to96/GUO/report.html 13 https://people.ece.cornell.edu/land/OldStudentProjects/cs490-95to96/GUO/report.html
  14 +https://software.intel.com/en-us/articles/the-basics-of-the-art-of-lighting-part-3-lighting-and-shaders/
  15 +https://docs.unity3d.com/Manual/Lighting.html
@@ -27,18 +27,27 @@ use crate::transform::TMatrix; @@ -27,18 +27,27 @@ use crate::transform::TMatrix;
27 use crate::trigonometry::Trig; 27 use crate::trigonometry::Trig;
28 use crate::vector::Vector; 28 use crate::vector::Vector;
29 29
  30 +#[derive(Debug, Clone)]
  31 +pub struct Face<T>
  32 +where T: Add + Sub + Neg + Mul + Div + Copy + Trig {
  33 + corners :Vec<usize>,
  34 + normal :Option<Vector<T>>,
  35 +}
  36 +
30 #[derive(Debug)] 37 #[derive(Debug)]
31 pub struct Polyeder<T> 38 pub struct Polyeder<T>
32 -where T: Add + Sub + Neg + Mul + Div + Debug + Copy + Trig {  
33 - points :Vec<Vector<T>>,  
34 - faces :Vec<Vec<usize>>,  
35 - normals :Vec<Vector<T>>, 39 +where T: Add + Sub + Neg + Mul + Div + Copy + Trig {
  40 + points :Vec<Vector<T>>,
  41 + faces :Vec<Face<T>>,
36 } 42 }
37 43
38 pub trait Primitives<T> 44 pub trait Primitives<T>
39 where T: Add + Sub + Neg + Mul + Div + Debug + Copy + Trig + From<i32> { 45 where T: Add + Sub + Neg + Mul + Div + Debug + Copy + Trig + From<i32> {
40 fn transform(&self, m :&TMatrix<T>) -> Self; 46 fn transform(&self, m :&TMatrix<T>) -> Self;
41 - fn project(&self, camera :&Camera<T>) -> Vec<Polygon>; 47 + fn project( &self
  48 + , camera :&Camera<T>
  49 + , light :&DirectLight<T>
  50 + , col :u32 ) -> Vec<(Polygon, u32)>;
42 } 51 }
43 52
44 pub struct Camera<T> 53 pub struct Camera<T>
@@ -48,6 +57,11 @@ where T: Add + Sub + Neg + Mul + Div + Debug + Copy + Trig + From<i32> { @@ -48,6 +57,11 @@ where T: Add + Sub + Neg + Mul + Div + Debug + Copy + Trig + From<i32> {
48 project :TMatrix<T>, 57 project :TMatrix<T>,
49 } 58 }
50 59
  60 +pub struct DirectLight<T>
  61 +where T: Add + Sub + Neg + Mul + Div + Debug + Copy + Trig + From<i32> {
  62 + direction: Vector<T>,
  63 +}
  64 +
51 impl<T> Camera<T> 65 impl<T> Camera<T>
52 where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> 66 where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
53 + Mul<Output = T> + Div<Output = T> 67 + Mul<Output = T> + Div<Output = T>
@@ -83,10 +97,46 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> @@ -83,10 +97,46 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
83 } 97 }
84 } 98 }
85 99
  100 +impl<T> DirectLight<T>
  101 +where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
  102 + + Mul<Output = T> + Div<Output = T>
  103 + + Debug + Copy + Trig + From<i32> {
  104 + pub fn new(v :Vector<T>) -> Self {
  105 + DirectLight{ direction: v }
  106 + }
  107 +
  108 + pub fn dir(&self) -> Vector<T> {
  109 + self.direction
  110 + }
  111 +}
  112 +
  113 +impl<T> Face<T>
  114 +where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
  115 + + Mul<Output = T> + Div<Output = T>
  116 + + Debug + Copy + Trig + From<i32> {
  117 + fn new(corners :Vec<usize>, ps :&[Vector<T>]) -> Self {
  118 + let mut f = Face{ corners: corners, normal: None };
  119 + f.update_normal(ps);
  120 + f
  121 + }
  122 +
  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]];
  126 + self.normal = Some(edge10 * edge12);
  127 + }
  128 +}
  129 +
86 impl<T> Polyeder<T> 130 impl<T> Polyeder<T>
87 where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> 131 where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
88 + Mul<Output = T> + Div<Output = T> 132 + Mul<Output = T> + Div<Output = T>
89 + Debug + Copy + Trig + From<i32> { 133 + Debug + Copy + Trig + From<i32> {
  134 + fn update_normals(&mut self) {
  135 + for f in self.faces.iter_mut() {
  136 + f.update_normal(&self.points);
  137 + }
  138 + }
  139 +
90 // https://rechneronline.de/pi/tetrahedron.php 140 // https://rechneronline.de/pi/tetrahedron.php
91 pub fn tetrahedron(a :T) -> Polyeder<T> { 141 pub fn tetrahedron(a :T) -> Polyeder<T> {
92 let f0 :T = 0.into(); 142 let f0 :T = 0.into();
@@ -106,49 +156,86 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> @@ -106,49 +156,86 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
106 // half the deeps in z 156 // half the deeps in z
107 let _zh :T = T::sqrt(f3).unwrap() / f4 * a; 157 let _zh :T = T::sqrt(f3).unwrap() / f4 * a;
108 158
109 - Polyeder{ points: vec!( Vector( f0, yc, f0)  
110 - , Vector(-ah, -yi, -zi)  
111 - , Vector( ah, -yi, -zi)  
112 - , Vector( f0, -yi, zc) )  
113 - , faces: vec!( vec!(1, 2, 3)  
114 - , vec!(1, 0, 2)  
115 - , vec!(3, 0, 1)  
116 - , vec!(2, 0, 3) )} 159 + let ps = vec!( Vector( f0, yc, f0)
  160 + , Vector(-ah, -yi, -zi)
  161 + , Vector( ah, -yi, -zi)
  162 + , Vector( f0, -yi, zc) );
  163 +
  164 + let fs = vec!( Face::new(vec!(1, 2, 3), &ps)
  165 + , Face::new(vec!(1, 0, 2), &ps)
  166 + , Face::new(vec!(3, 0, 1), &ps)
  167 + , Face::new(vec!(2, 0, 3), &ps) );
  168 +
  169 + Polyeder{ points: ps, faces: fs }
  170 + }
  171 +
  172 + pub fn triangle(a :T) -> Polyeder<T> {
  173 + let f0 :T = 0.into();
  174 + let f3 :T = 3.into();
  175 + let f6 :T = 6.into();
  176 + let zi :T = T::sqrt(f3).unwrap() / f6 * a;
  177 + let zc :T = T::sqrt(f3).unwrap() / f3 * a;
  178 + let ah :T = a / 2.into();
  179 +
  180 + let ps = vec!( Vector(-ah, f0, -zi)
  181 + , Vector( f0, f0, zc)
  182 + , Vector( ah, f0, -zi) );
  183 +
  184 + let fs = vec!(Face::new(vec!(0, 1, 2), &ps));
  185 +
  186 + println!("== {:?}", fs);
  187 +
  188 + Polyeder{ points: ps, faces: fs }
117 } 189 }
118 190
119 pub fn cube(a :T) -> Polyeder<T> { 191 pub fn cube(a :T) -> Polyeder<T> {
120 let ah :T = a / From::<i32>::from(2); 192 let ah :T = a / From::<i32>::from(2);
121 193
122 - Polyeder{ points: vec!( Vector(-ah, ah, -ah) // 0 => front 1  
123 - , Vector(-ah, -ah, -ah) // 1 => front 2  
124 - , Vector( ah, -ah, -ah) // 2 => front 3  
125 - , Vector( ah, ah, -ah) // 3 => front 4  
126 - , Vector(-ah, ah, ah) // 4 => back 1  
127 - , Vector(-ah, -ah, ah) // 5 => back 2  
128 - , Vector( ah, -ah, ah) // 6 => back 3  
129 - , Vector( ah, ah, ah) ) // 7 => back 4  
130 - , faces: vec!( vec!(0, 1, 2, 3) // front  
131 - , vec!(7, 6, 5, 4) // back  
132 - , vec!(1, 5, 6, 2) // top  
133 - , vec!(0, 3, 7, 4) // bottom  
134 - , vec!(0, 4, 5, 1) // left  
135 - , vec!(2, 6, 7, 3) )} // right 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
  202 +
  203 + let fs = vec!( Face::new(vec!(0, 1, 2, 3), &ps) // front
  204 + , Face::new(vec!(7, 6, 5, 4), &ps) // back
  205 + , Face::new(vec!(1, 5, 6, 2), &ps) // top
  206 + , Face::new(vec!(0, 3, 7, 4), &ps) // bottom
  207 + , Face::new(vec!(0, 4, 5, 1), &ps) // left
  208 + , Face::new(vec!(2, 6, 7, 3), &ps) ); // right
  209 +
  210 + Polyeder{ points: ps, faces: fs }
136 } 211 }
137 } 212 }
138 213
139 impl<T> Primitives<T> for Polyeder<T> 214 impl<T> Primitives<T> for Polyeder<T>
140 where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> 215 where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
141 + Mul<Output = T> + Div<Output = T> 216 + Mul<Output = T> + Div<Output = T>
142 - + Debug + Copy + Trig + From<i32> + From<i32> { 217 + + Debug + Copy + Trig + From<i32> + PartialOrd {
143 fn transform(&self, m :&TMatrix<T>) -> Self { 218 fn transform(&self, m :&TMatrix<T>) -> Self {
144 - Polyeder{ points: self.points.iter().map(|p| m.apply(p)).collect()  
145 - , faces: self.faces.to_vec() } 219 + let Polyeder{ points: ps, faces: fs } = self;
  220 +
  221 + let mut p = Polyeder{ points: ps.iter().map(|p| m.apply(p)).collect()
  222 + , faces: fs.to_vec() };
  223 +
  224 + // TODO alternatively we could rotate the normals too, but this cannot
  225 + // done with the original matrix… the question is, what is faster.
  226 + p.update_normals();
  227 + p
146 } 228 }
147 229
148 // TODO for now we assume already prejected vertices (points) 230 // TODO for now we assume already prejected vertices (points)
149 // in future we need to distinguish more clear between vertex and point 231 // in future we need to distinguish more clear between vertex and point
150 // and projected_point. 232 // and projected_point.
151 - fn project(&self, _camera :&Camera<T>) -> Vec<Polygon> { 233 + fn project( &self
  234 + , camera :&Camera<T>
  235 + , light :&DirectLight<T>
  236 + , color :u32 ) -> Vec<(Polygon, u32)> {
  237 + // Helper to create a Polygon from Coordinates…
  238 + // TODO probably there needs to be a Polygon constructor for this.
152 fn polygon<I>(c :I) -> Polygon 239 fn polygon<I>(c :I) -> Polygon
153 where I: Iterator<Item = Coordinate> { 240 where I: Iterator<Item = Coordinate> {
154 Polygon(Coordinates(c.collect())) 241 Polygon(Coordinates(c.collect()))
@@ -156,12 +243,34 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> @@ -156,12 +243,34 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
156 243
157 // this one does the projection... as the projection was the last 244 // this one does the projection... as the projection was the last
158 // matrix we do not need to do it here. 245 // matrix we do not need to do it here.
159 - // let to_coord = |p :&usize| _camera.project(self.points[*p]);  
160 - let to_coord = |p :&usize| {  
161 - let v = self.points[*p];  
162 - Coordinate(v.x().round(), v.y().round()) };  
163 - let to_poly = |f :&Vec<usize>| polygon(f.iter().map(to_coord)); 246 + let to_coord = |p :&usize| camera.project(self.points[*p]);
  247 + let to_poly = |f :&Face<T>| {
  248 + let pg = polygon(f.corners.iter().map(to_coord));
  249 + let mut r :T = (((color >> 16) & 0xFF) as i32).into();
  250 + let mut g :T = (((color >> 8) & 0xFF) as i32).into();
  251 + let mut b :T = (((color ) & 0xFF) as i32).into();
  252 + let lf :T = match f.normal {
  253 + None => 1.into(),
  254 + Some(n) => n.dot(light.dir())
  255 + / (n.mag() * light.dir().mag()),
  256 + };
  257 +
  258 + if lf < 0.into() {
  259 + r = r * -lf;
  260 + g = g * -lf;
  261 + b = b * -lf;
  262 +
  263 + let c :u32 = (r.round() as u32) << 16
  264 + | (g.round() as u32) << 8
  265 + | (b.round() as u32);
  266 +
  267 + Some((pg, c))
  268 + } else {
  269 + None
  270 + }};
164 271
165 - self.faces.iter().map(to_poly).collect() 272 + let mut ps :Vec<(Polygon, u32)> = self.faces.iter().filter_map(to_poly).collect();
  273 + ps.sort_by(|a, b| a.1.cmp(&b.1));
  274 + ps
166 } 275 }
167 } 276 }
@@ -39,7 +39,7 @@ use fractional::transform::{TMatrix, translate, rotate_x, rotate_y, rotate_z, ro @@ -39,7 +39,7 @@ use fractional::transform::{TMatrix, translate, rotate_x, rotate_y, rotate_z, ro
39 use fractional::xcb::XcbEasel; 39 use fractional::xcb::XcbEasel;
40 use fractional::easel::Canvas; 40 use fractional::easel::Canvas;
41 41
42 -use fractional::geometry::{Camera,Polyeder,Primitives}; 42 +use fractional::geometry::{Camera,DirectLight,Polyeder,Primitives};
43 43
44 fn mean(v: &Vec<i64>) -> Result<Fractional, TryFromIntError> { 44 fn mean(v: &Vec<i64>) -> Result<Fractional, TryFromIntError> {
45 let r = v.iter().fold(0, |acc, x| acc + x); 45 let r = v.iter().fold(0, |acc, x| acc + x);
@@ -162,16 +162,16 @@ fn _vector<T>(v1 :Vector<T>, v2 :Vector<T>, s :T) @@ -162,16 +162,16 @@ fn _vector<T>(v1 :Vector<T>, v2 :Vector<T>, s :T)
162 + Mul<Output = T> + Div<Output = T> + Trig + Copy + Display { 162 + Mul<Output = T> + Div<Output = T> + Trig + Copy + Display {
163 println!("{:>14} : {}", "Vector v1", v1); 163 println!("{:>14} : {}", "Vector v1", v1);
164 println!("{:>14} : {}", "Vector v2", v2); 164 println!("{:>14} : {}", "Vector v2", v2);
165 - println!("{:>14} : {}", "abs v1", v1.abs()); 165 + println!("{:>14} : {}", "magnitude v1", v1.mag());
166 println!("{:>14} : {}", "-v1", -v1); 166 println!("{:>14} : {}", "-v1", -v1);
167 println!("{:>14} : {}", "v1 + v1", v1 + v1); 167 println!("{:>14} : {}", "v1 + v1", v1 + v1);
168 println!("{:>14} : {}", "v1 - v1", v1 - v1); 168 println!("{:>14} : {}", "v1 - v1", v1 - v1);
169 println!("{:>14} : {}", "v2 - v1", v2 - v1); 169 println!("{:>14} : {}", "v2 - v1", v2 - v1);
170 println!("{:>14} : {}", format!("v1 * {}", s), v1.mul(&s)); 170 println!("{:>14} : {}", format!("v1 * {}", s), v1.mul(&s));
171 println!("{:>14} : {}", "norm v1", v1.norm()); 171 println!("{:>14} : {}", "norm v1", v1.norm());
172 - println!("{:>14} : {}", "abs norm v1", v1.norm().abs());  
173 - println!("{:>14} : {}", "abs v1", v1.abs());  
174 - println!("{:>14} : {}", "norm * abs", v1.norm().mul(&v1.abs())); 172 + println!("{:>14} : {}", "magnitude norm v1", v1.norm().mag());
  173 + println!("{:>14} : {}", "magnitude v1", v1.mag());
  174 + println!("{:>14} : {}", "norm * magnitude", v1.norm().mul(&v1.mag()));
175 println!("{:>14} : {}", "distance v1 v2", v1.distance(v2)); 175 println!("{:>14} : {}", "distance v1 v2", v1.distance(v2));
176 println!("{:>14} : {}", "distance v2 v1", v2.distance(v1)); 176 println!("{:>14} : {}", "distance v2 v1", v2.distance(v1));
177 println!("{:>14} : {}", "v1 dot v2", v1.dot(v2)); 177 println!("{:>14} : {}", "v1 dot v2", v1.dot(v2));
@@ -313,15 +313,17 @@ fn _line() { @@ -313,15 +313,17 @@ fn _line() {
313 fn _democanvas<T>( xcb :&XcbEasel 313 fn _democanvas<T>( xcb :&XcbEasel
314 , title :&'static str 314 , title :&'static str
315 , tx :mpsc::Sender<i32> 315 , tx :mpsc::Sender<i32>
  316 + , _triangle :Polyeder<T>
316 , tetrahedron :Polyeder<T> 317 , tetrahedron :Polyeder<T>
317 - , cube :Polyeder<T> ) 318 + , cube :Polyeder<T>
  319 + , light :DirectLight<T> )
318 where T: 'static + Add<Output = T> + Sub<Output = T> + Neg<Output = T> 320 where T: 'static + Add<Output = T> + Sub<Output = T> + Neg<Output = T>
319 + Mul<Output = T> + Div<Output = T> 321 + Mul<Output = T> + Div<Output = T>
320 - + Debug + Copy + Trig + Send + From<i32> { 322 + + Debug + Copy + Trig + Send + From<i32> + PartialOrd {
321 323
322 let mut canvas = xcb.canvas(151, 151).unwrap(); 324 let mut canvas = xcb.canvas(151, 151).unwrap();
323 - let camera = Camera::<T>::new(&canvas, 45); // the orig. view angle  
324 - // was 50. 325 + let camera = Camera::<T>::new(&canvas, 45); // the orig. view angle
  326 + // was 50.
325 327
326 canvas.set_title(title); 328 canvas.set_title(title);
327 canvas.init_events(); 329 canvas.init_events();
@@ -333,24 +335,31 @@ fn _democanvas<T>( xcb :&XcbEasel @@ -333,24 +335,31 @@ fn _democanvas<T>( xcb :&XcbEasel
333 let mut last = Instant::now(); 335 let mut last = Instant::now();
334 336
335 let t :TMatrix<T> = translate(Vector(0.into(), 0.into(), 150.into())); 337 let t :TMatrix<T> = translate(Vector(0.into(), 0.into(), 150.into()));
336 - let p :TMatrix<T> = camera.get_projection(); 338 + // We do not need this here… it is used within projection…
  339 + // let p :TMatrix<T> = camera.get_projection();
337 340
338 loop { 341 loop {
339 let deg = ((start.elapsed() / 25).as_millis() % 360) as i32; 342 let deg = ((start.elapsed() / 25).as_millis() % 360) as i32;
340 343
341 let rz :TMatrix<T> = rotate_z(deg); 344 let rz :TMatrix<T> = rotate_z(deg);
342 345
343 - let rot1 = TMatrix::combine(vec!(rz, rotate_x(-deg*2), t, p));  
344 - let rot2 = TMatrix::combine(vec!(rz, rotate_y(-deg*2), t, p)); 346 + // I can not apply the projection in one turn, as I generate the
  347 + // normals always… and this is no longer possible after the
  348 + // projection…
  349 + // let rot1 = TMatrix::combine(vec!(rz, rotate_x(-deg*2), t, p));
  350 + // let rot2 = TMatrix::combine(vec!(rz, rotate_y(-deg*2), t, p));
  351 + let rot1 = TMatrix::combine(vec!(rz, rotate_x(-deg*2), t));
  352 + let rot2 = TMatrix::combine(vec!(rz, rotate_y(-deg*2), t));
345 353
346 let objects = vec!( (tetrahedron.transform(&rot1), 0xFFFF00) 354 let objects = vec!( (tetrahedron.transform(&rot1), 0xFFFF00)
347 , ( cube.transform(&rot2), 0x0000FF) ); 355 , ( cube.transform(&rot2), 0x0000FF) );
  356 + //let objects = vec!( (triangle.transform(&rot1), 0xFFFF00) );
348 357
349 canvas.clear(); 358 canvas.clear();
350 359
351 for (o, color) in objects { 360 for (o, color) in objects {
352 - for pg in o.project(&camera) {  
353 - canvas.draw(&pg, Coordinate(0,0), color); 361 + for (pg, c) in o.project(&camera, &light, color) {
  362 + canvas.draw(&pg, Coordinate(0,0), c);
354 } 363 }
355 } 364 }
356 365
@@ -400,11 +409,17 @@ fn main() { @@ -400,11 +409,17 @@ fn main() {
400 let (tx, rx) = mpsc::channel(); 409 let (tx, rx) = mpsc::channel();
401 410
402 _democanvas( &xcb, "Something...(f64)", tx.clone() 411 _democanvas( &xcb, "Something...(f64)", tx.clone()
  412 + , Polyeder::triangle(60.0)
403 , Polyeder::tetrahedron(60.0) 413 , Polyeder::tetrahedron(60.0)
404 - , Polyeder::cube(60.0) ); 414 + , Polyeder::cube(60.0)
  415 + , DirectLight::new(Vector(0.0, 0.0, 1.0)) );
405 _democanvas( &xcb, "Something...(Fractional)", tx.clone() 416 _democanvas( &xcb, "Something...(Fractional)", tx.clone()
  417 + , Polyeder::triangle(Fractional(60,1))
406 , Polyeder::tetrahedron(Fractional(60,1)) 418 , Polyeder::tetrahedron(Fractional(60,1))
407 - , Polyeder::cube(Fractional(60,1)) ); 419 + , Polyeder::cube(Fractional(60,1))
  420 + , DirectLight::new(Vector( Fractional(0,1)
  421 + , Fractional(0,1)
  422 + , Fractional(1,1) )) );
408 423
409 for x in rx { 424 for x in rx {
410 match x { 425 match x {
@@ -34,7 +34,7 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> @@ -34,7 +34,7 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
34 pub fn y(self) -> T { self.1 } 34 pub fn y(self) -> T { self.1 }
35 pub fn z(self) -> T { self.2 } 35 pub fn z(self) -> T { self.2 }
36 36
37 - pub fn abs(self) -> T { 37 + pub fn mag(self) -> T {
38 let Vector(x, y, z) = self; 38 let Vector(x, y, z) = self;
39 (x * x + y * y + z * z).sqrt().unwrap() 39 (x * x + y * y + z * z).sqrt().unwrap()
40 } 40 }
@@ -53,12 +53,12 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> @@ -53,12 +53,12 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T>
53 53
54 pub fn norm(self) -> Self { 54 pub fn norm(self) -> Self {
55 // TODO This can result in 0 or inf Vectors… 55 // TODO This can result in 0 or inf Vectors…
56 - // Maybe we need to handle zero and inf abs here…  
57 - self.mul(&self.abs()) 56 + // Maybe we need to handle zero and inf magnitude here…
  57 + self.mul(&self.mag().recip())
58 } 58 }
59 59
60 pub fn distance(self, other :Self) -> T { 60 pub fn distance(self, other :Self) -> T {
61 - (self - other).abs() 61 + (self - other).mag()
62 } 62 }
63 } 63 }
64 64
Please register or login to post a comment