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 | 18 | // You should have received a copy of the GNU General Public License |
| 19 | 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 | 22 | use std::ops::{Add,Sub,Neg,Mul,Div}; |
| 23 | 23 | use std::fmt::Debug; |
| 24 | 24 | |
| 25 | 25 | use crate::easel::{Canvas,Coordinate,Coordinates,Polygon}; |
| 26 | -use crate::transform::TMatrix; | |
| 26 | +use crate::transform::{TMatrix, Transformable}; | |
| 27 | 27 | use crate::trigonometry::Trig; |
| 28 | 28 | use crate::vector::Vector; |
| 29 | 29 | |
| ... | ... | @@ -34,10 +34,113 @@ where T: Add + Sub + Neg + Mul + Div + Copy + Trig { |
| 34 | 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 | 140 | #[derive(Debug)] |
| 38 | 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 | 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 | 168 | impl<T> Camera<T> |
| 66 | 169 | where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> |
| 67 | 170 | + Mul<Output = T> + Div<Output = T> |
| 68 | - + Debug + Copy + Trig + From<i32> { | |
| 171 | + + PartialEq + Debug + Copy + Trig + From<i32> { | |
| 69 | 172 | // This code assumes that the size of the viewport is always |
| 70 | 173 | // equal to the size of the physical screen… e.g. window/canvas thus some |
| 71 | 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 | 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 | 216 | impl<T> Face<T> |
| 114 | 217 | where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> |
| 115 | 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 | 221 | let mut f = Face{ corners: corners, normal: None }; |
| 119 | 222 | f.update_normal(ps); |
| 120 | 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 | 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 | 233 | impl<T> Polyeder<T> |
| 131 | 234 | where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> |
| 132 | 235 | + Mul<Output = T> + Div<Output = T> |
| 133 | - + Debug + Copy + Trig + From<i32> { | |
| 236 | + + PartialEq + Debug + Copy + Trig + From<i32> { | |
| 134 | 237 | fn update_normals(&mut self) { |
| 135 | 238 | for f in self.faces.iter_mut() { |
| 136 | 239 | f.update_normal(&self.points); |
| ... | ... | @@ -156,10 +259,10 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> |
| 156 | 259 | // half the deeps in z |
| 157 | 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 | 267 | let fs = vec!( Face::new(vec!(1, 2, 3), &ps) |
| 165 | 268 | , Face::new(vec!(1, 0, 2), &ps) |
| ... | ... | @@ -177,9 +280,9 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> |
| 177 | 280 | let zc :T = T::sqrt(f3).unwrap() / f3 * a; |
| 178 | 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 | 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 | 294 | pub fn cube(a :T) -> Polyeder<T> { |
| 192 | 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 | 306 | let fs = vec!( Face::new(vec!(0, 1, 2, 3), &ps) // front |
| 204 | 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 | 321 | fn transform(&self, m :&TMatrix<T>) -> Self { |
| 219 | 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 | 329 | // TODO alternatively we could rotate the normals too, but this cannot |
| 225 | 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 | 34 | use fractional::fractional::{Fractional, from_vector}; |
| 35 | 35 | use fractional::trigonometry::Trig; |
| 36 | 36 | use fractional::vector::Vector; |
| 37 | -use fractional::transform::TMatrix; | |
| 37 | +use fractional::transform::{TMatrix, Transformable}; | |
| 38 | 38 | |
| 39 | 39 | use fractional::xcb::XcbEasel; |
| 40 | 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 | 204 | + Debug + From<i32> + Copy + Display { |
| 205 | 205 | |
| 206 | 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 | 209 | println!(); |
| 209 | 210 | |
| 210 | 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 | 219 | let mi = fs.iter().map(|f| f(*d as i32)); |
| 219 | 220 | println!( "{:>14} : {}" |
| 220 | 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 | 238 | , 210, 225, 240, 270, 300, 315, 330 ].iter() { |
| 238 | 239 | println!( "{:>14} : {}" |
| 239 | 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 | 274 | let k = Vector(Fractional(-30,1), Fractional( 30,1), Fractional(0,1)); |
| 274 | 275 | |
| 275 | 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 | 281 | fn to_i32(x :Fractional) -> i32 { |
| 281 | 282 | let Fractional(n, d) = x; |
| ... | ... | @@ -294,9 +295,9 @@ fn _line() { |
| 294 | 295 | let k = Vector(-30.0, 30.0, 0.0); |
| 295 | 296 | |
| 296 | 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 | 302 | fn to_i32_2(x :f64) -> i32 { |
| 302 | 303 | x.round() as i32 |
| ... | ... | @@ -334,24 +335,15 @@ fn _democanvas<T>( xcb :&XcbEasel |
| 334 | 335 | let step = Duration::from_millis(25); |
| 335 | 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 | 340 | loop { |
| 344 | 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 | 347 | let rot1 = TMatrix::combine(vec!(rz, rx, t)); |
| 356 | 348 | let rot2 = TMatrix::combine(vec!(rz, ry, t)); |
| 357 | 349 | ... | ... |
| ... | ... | @@ -31,6 +31,11 @@ pub struct TMatrix<T>( (T, T, T, T) |
| 31 | 31 | , (T, T, T, T) ) |
| 32 | 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 | 39 | impl<T> TMatrix<T> |
| 35 | 40 | where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> |
| 36 | 41 | + Mul<Output = T> + Div<Output = T> |
| ... | ... | @@ -127,19 +132,20 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> |
| 127 | 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 | 136 | let TMatrix( (a11, a12, a13, a14) |
| 132 | 137 | , (a21, a22, a23, a24) |
| 133 | 138 | , (a31, a32, a33, a34) |
| 134 | 139 | , (a41, a42, a43, a44) ) = *self; |
| 135 | 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 | 18 | // You should have received a copy of the GNU General Public License |
| 19 | 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 | 22 | use std::ops::{Add, Sub, Neg, Mul, Div}; |
| 23 | 23 | |
| 24 | 24 | use crate::trigonometry::Trig; |
| 25 | +use crate::transform::{TMatrix, Transformable}; | |
| 25 | 26 | |
| 26 | 27 | #[derive(Debug, Eq, Clone, Copy)] |
| 27 | 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 | 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