Commit 9911ab0166cd4abf0e50252234b5dba8b1360b9b
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.
Showing
4 changed files
with
175 additions
and
61 deletions
| @@ -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