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