Commit 8f0edfaa14775e387ad3cbf852ce94e90a589790
1 parent
721b89a1
Start making an iterator from the line algorithm
Showing
3 changed files
with
140 additions
and
91 deletions
fractional/.swp
0 → 100644
No preview for this file type
@@ -56,46 +56,136 @@ pub struct Coordinate<T>(pub i32, pub i32, pub T); | @@ -56,46 +56,136 @@ pub struct Coordinate<T>(pub i32, pub i32, pub T); | ||
56 | #[derive(Debug, Clone)] | 56 | #[derive(Debug, Clone)] |
57 | pub struct Coordinates<T>(pub Vec<Coordinate<T>>); | 57 | pub struct Coordinates<T>(pub Vec<Coordinate<T>>); |
58 | 58 | ||
59 | +#[derive(Debug, Clone)] | ||
60 | +pub struct LineIterator<T> where T: Debug { | ||
61 | + a :Option<Coordinate<T>> | ||
62 | + , b :Coordinate<T> | ||
63 | + , dx :i32 | ||
64 | + , dy :i32 | ||
65 | + , dzx :T | ||
66 | + , dzy :T | ||
67 | + , sx :i32 | ||
68 | + , sy :i32 | ||
69 | + , err :i32 | ||
70 | + , only_edges :bool | ||
71 | +} | ||
72 | + | ||
73 | +impl<T> Iterator for LineIterator<T> | ||
74 | +where T: Add<Output = T> + Debug + Copy + From<i32> { | ||
75 | + type Item = Coordinate<T>; | ||
76 | + | ||
77 | + fn next(&mut self) -> Option<Self::Item> { | ||
78 | + let Coordinate(ax, ay, az) = match self.a { | ||
79 | + None => self.b, | ||
80 | + Some(a) => a, | ||
81 | + }; | ||
82 | + let Coordinate(bx, by, _) = self.b; | ||
83 | + | ||
84 | + //println!("== {:?}", self); | ||
85 | + | ||
86 | + if ax != bx || ay != by { | ||
87 | + match (2 * self.err >= self.dy, 2 * self.err <= self.dx ) { | ||
88 | + (true, false) => { | ||
89 | + let r = self.a; | ||
90 | + self.a = Some(Coordinate(ax+self.sx, ay, az+self.dzx)); | ||
91 | + self.err = self.err + self.dy; | ||
92 | + if self.only_edges { self.next() } else { r } | ||
93 | + }, | ||
94 | + (false, true) => { | ||
95 | + let r = self.a; | ||
96 | + self.a = Some(Coordinate(ax, ay+self.sy, az+self.dzy)); | ||
97 | + self.err = self.err + self.dx; | ||
98 | + r | ||
99 | + }, | ||
100 | + _ => { | ||
101 | + let r = self.a; | ||
102 | + self.a = Some(Coordinate( ax + self.sx | ||
103 | + , ay + self.sy | ||
104 | + , az + self.dzy )); | ||
105 | + self.err = self.err + self.dx + self.dy; | ||
106 | + r | ||
107 | + }, | ||
108 | + } | ||
109 | + } else { | ||
110 | + match self.a { | ||
111 | + None => None, | ||
112 | + Some(a) => { self.a = None; Some(a) } | ||
113 | + } | ||
114 | + } | ||
115 | + } | ||
116 | +} | ||
117 | + | ||
59 | impl<T> Coordinate<T> | 118 | impl<T> Coordinate<T> |
60 | where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | 119 | where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> |
61 | - + Clone + Copy + From<i32> { | 120 | + + Debug + Clone + Copy + From<i32> { |
121 | + fn iter(self, b :&Self, only_edges :bool) -> LineIterator<T> { | ||
122 | + let Coordinate(ax, ay, az) = self; | ||
123 | + let Coordinate(bx, by, bz) = *b; | ||
124 | + | ||
125 | + let dx = (bx - ax).abs(); | ||
126 | + let dy = -(by - ay).abs(); | ||
127 | + let size = cmp::min(dx, -dy); | ||
128 | + let dz = (bz - az) / size.into(); | ||
129 | + | ||
130 | + LineIterator { a: Some(self) | ||
131 | + , b: *b | ||
132 | + , dx: dx | ||
133 | + , dy: dy | ||
134 | + , dzx: if size == dx { dz } else { 0.into() } | ||
135 | + , dzy: if size == -dy { dz } else { 0.into() } | ||
136 | + , sx: if ax < bx { 1 } else { -1 } | ||
137 | + , sy: if ay < by { 1 } else { -1 } | ||
138 | + , err: dx + dy | ||
139 | + , only_edges: only_edges | ||
140 | + } | ||
141 | + } | ||
142 | + | ||
62 | // Tail recursive Bresenham line with integer incremental error. | 143 | // Tail recursive Bresenham line with integer incremental error. |
63 | fn line(self, b :&Self) -> Vec<Self> { | 144 | fn line(self, b :&Self) -> Vec<Self> { |
64 | - fn inner<T>( v :&mut [Coordinate<T>] | ||
65 | - , bx :i32, by :i32 | ||
66 | - , dx :i32, dy :i32 | ||
67 | - , sx :i32, sy :i32 | ||
68 | - , dz :T, err :i32) | ||
69 | - where T: Add<Output = T> + Copy { | ||
70 | - | ||
71 | - let Coordinate(x, y, z) = v[0]; | ||
72 | - | ||
73 | - if x != bx || y != by { | ||
74 | - let (x, y, z, err) = match (2*err >= dy, 2*err <= dx) { | ||
75 | - (true, false) => (x + sx, y, z + dz, err + dy ), | ||
76 | - (false, true) => ( x, y + sy, z + dz, err + dx ), | ||
77 | - _ => (x + sx, y + sy, z + dz, err + dx + dy ), | ||
78 | - }; | ||
79 | - v[1] = Coordinate(x, y, z); | ||
80 | - inner(&mut v[1..], bx, by, dx, dy, sx, sy, dz, err); | 145 | + self.iter(b, false).collect() |
146 | + } | ||
147 | + | ||
148 | + /* | ||
149 | + * Special line algorithm just putting the outermost x values per | ||
150 | + * line into the resulting Vector. | ||
151 | + * This expects y of b larger than y of self. | ||
152 | + */ | ||
153 | + fn edge(self, b :&Self) -> Vec<Self> { | ||
154 | + println!("== New edge: {:?} - {:?}", self, b); | ||
155 | + self.iter(b, true).collect() | ||
156 | + /* | ||
157 | + let Coordinate(mut x, mut y, mut z) = self; | ||
158 | + let Coordinate( bx, by, bz) = *b; | ||
159 | + | ||
160 | + // next should be called with the negative of this… but dz depends | ||
161 | + // on the positive this. | ||
162 | + let dy = -(by - y).abs(); | ||
163 | + let dx = (bx - x).abs(); | ||
164 | + let sx = if x < bx { 1 } else { -1 }; | ||
165 | + let dz = (bz - z) / (-dy).into(); | ||
166 | + let mut err = dx + dy; | ||
167 | + | ||
168 | + let mut v = Vec::<Coordinate<T>>::with_capacity((-dy) as usize); | ||
169 | + | ||
170 | + while y != by { | ||
171 | + match (2*err >= dy, 2*err <= dx) { | ||
172 | + (true, false) => { x = x + sx | ||
173 | + ; err = err + dy }, | ||
174 | + (false, true) => { v.push(Coordinate(x, y, z)) | ||
175 | + ; y = y + 1 | ||
176 | + ; z = z + dz | ||
177 | + ; err = err + dx }, | ||
178 | + _ => { v.push(Coordinate(x, y, z)) | ||
179 | + ; x = x + sx | ||
180 | + ; y = y + 1 | ||
181 | + ; z = z + dz | ||
182 | + ; err = err + dx + dy }, | ||
81 | } | 183 | } |
82 | } | 184 | } |
83 | 185 | ||
84 | - let Coordinate(ax, ay, az) = self; | ||
85 | - let Coordinate(bx, by, bz) = *b; | ||
86 | - | ||
87 | - let dx = (bx - ax).abs(); | ||
88 | - let sx :i32 = if ax < bx { 1 } else { -1 }; | ||
89 | - let dy = (by - ay).abs(); | ||
90 | - let sy :i32 = if ay < by { 1 } else { -1 }; | ||
91 | - let size = cmp::max(dx, dy); | ||
92 | - let dz = (bz - az) / size.into(); | ||
93 | - | ||
94 | - let mut v :Vec<Self> = vec!( Coordinate(0, 0, 0.into()) | ||
95 | - ; (size as usize) + 1); | ||
96 | - v[0] = Coordinate(ax, ay, az); | ||
97 | - inner(&mut v, bx, by, dx, -dy, sx, sy, dz, dx - dy); | 186 | + v.push(*b); |
98 | v | 187 | v |
188 | + */ | ||
99 | } | 189 | } |
100 | } | 190 | } |
101 | 191 | ||
@@ -148,7 +238,7 @@ pub struct Line<T>(pub Coordinate<T>, pub Coordinate<T>); | @@ -148,7 +238,7 @@ pub struct Line<T>(pub Coordinate<T>, pub Coordinate<T>); | ||
148 | 238 | ||
149 | impl<T> Drawable<T> for Line<T> | 239 | impl<T> Drawable<T> for Line<T> |
150 | where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | 240 | where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> |
151 | - + Clone + Copy + From<i32> { | 241 | + + Debug + Clone + Copy + From<i32> { |
152 | fn plot(&self) -> Coordinates<T> { | 242 | fn plot(&self) -> Coordinates<T> { |
153 | let Line(a, b) = *self; | 243 | let Line(a, b) = *self; |
154 | Coordinates(a.line(&b)) | 244 | Coordinates(a.line(&b)) |
@@ -201,7 +291,7 @@ pub struct Polyline<T>(pub Coordinates<T>); | @@ -201,7 +291,7 @@ pub struct Polyline<T>(pub Coordinates<T>); | ||
201 | 291 | ||
202 | impl<T> Drawable<T> for Polyline<T> | 292 | impl<T> Drawable<T> for Polyline<T> |
203 | where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | 293 | where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> |
204 | - + Clone + Copy + From<i32> { | 294 | + + Debug + Clone + Copy + From<i32> { |
205 | fn plot(&self) -> Coordinates<T> { | 295 | fn plot(&self) -> Coordinates<T> { |
206 | let Polyline(Coordinates(cs)) = self; | 296 | let Polyline(Coordinates(cs)) = self; |
207 | 297 | ||
@@ -235,7 +325,7 @@ pub struct Polygon<T>(pub Coordinates<T>); | @@ -235,7 +325,7 @@ pub struct Polygon<T>(pub Coordinates<T>); | ||
235 | 325 | ||
236 | impl<T> Drawable<T> for Polygon<T> | 326 | impl<T> Drawable<T> for Polygon<T> |
237 | where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | 327 | where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> |
238 | - + Clone + Copy + From<i32> { | 328 | + + Debug + Clone + Copy + From<i32> { |
239 | fn plot(&self) -> Coordinates<T> { | 329 | fn plot(&self) -> Coordinates<T> { |
240 | let Polygon(Coordinates(cs)) = self; | 330 | let Polygon(Coordinates(cs)) = self; |
241 | 331 | ||
@@ -267,45 +357,6 @@ where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | @@ -267,45 +357,6 @@ where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | ||
267 | + Debug + Clone + Copy + From<i32> { | 357 | + Debug + Clone + Copy + From<i32> { |
268 | fn fill(&self) -> Coordinates<T> { | 358 | fn fill(&self) -> Coordinates<T> { |
269 | 359 | ||
270 | - /* bresenham kind of thing to get the outer x values for each y of one | ||
271 | - * edge of the polygon. */ | ||
272 | - fn walk_edge<T>( a :Coordinate<T> | ||
273 | - , b :Coordinate<T> ) -> Vec<Coordinate<T>> | ||
274 | - where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | ||
275 | - + From<i32> + Debug + Copy { | ||
276 | - | ||
277 | - let Coordinate(mut x, mut y, mut z) = a; | ||
278 | - let Coordinate( bx, by, bz) = b; | ||
279 | - | ||
280 | - // next should be called with the negative of this… but dz depends | ||
281 | - // on the positive this. | ||
282 | - let dy = -(by - y).abs(); | ||
283 | - let dx = (bx - x).abs(); | ||
284 | - let sx = if x < bx { 1 } else { -1 }; | ||
285 | - let dz = (bz - z) / (-dy).into(); | ||
286 | - let mut err = dx + dy; | ||
287 | - | ||
288 | - let mut v = Vec::<Coordinate<T>>::with_capacity((-dy) as usize); | ||
289 | - | ||
290 | - while y != by { | ||
291 | - match (2*err >= dy, 2*err <= dx) { | ||
292 | - (true, false) => { x = x + sx | ||
293 | - ; err = err + dy }, | ||
294 | - (false, true) => { v.push(Coordinate(x, y, z)) | ||
295 | - ; y = y + 1 | ||
296 | - ; z = z + dz | ||
297 | - ; err = err + dx }, | ||
298 | - _ => { v.push(Coordinate(x, y, z)) | ||
299 | - ; x = x + sx | ||
300 | - ; y = y + 1 | ||
301 | - ; z = z + dz | ||
302 | - ; err = err + dx + dy }, | ||
303 | - } | ||
304 | - } | ||
305 | - | ||
306 | - v | ||
307 | - } | ||
308 | - | ||
309 | fn next_y<T>( cs :&[Coordinate<T>] | 360 | fn next_y<T>( cs :&[Coordinate<T>] |
310 | , c :usize | 361 | , c :usize |
311 | , f :&dyn Fn(usize) -> usize) -> Option<usize> { | 362 | , f :&dyn Fn(usize) -> usize) -> Option<usize> { |
@@ -353,24 +404,22 @@ where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | @@ -353,24 +404,22 @@ where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | ||
353 | let mut l_edge :Vec<Coordinate<T>> = Vec::new(); | 404 | let mut l_edge :Vec<Coordinate<T>> = Vec::new(); |
354 | let mut r_edge :Vec<Coordinate<T>> = Vec::new(); | 405 | let mut r_edge :Vec<Coordinate<T>> = Vec::new(); |
355 | 406 | ||
356 | - while l.1 != None || r.1 != None { | ||
357 | - match l.1 { | ||
358 | - None => {}, | ||
359 | - Some(a) => { | ||
360 | - println!("== l: [{:?}] - {:?}", l, cs[a]); | ||
361 | - l_edge.append(&mut walk_edge(cs[l.0], cs[a])); | ||
362 | - l = (a, next_y(cs, a, &left)); | 407 | + let append_edge = | v :&mut Vec<Coordinate<T>> |
408 | + , e :&(usize, Option<usize>) | { | ||
409 | + match *e { | ||
410 | + (_, None) => *e, | ||
411 | + (a, Some(b)) => { | ||
412 | + println!("== l: [{:?}] - {:?}", e, cs[b]); | ||
413 | + let mut edge = cs[a].edge(&cs[b]); | ||
414 | + v.append(&mut edge); | ||
415 | + (b, next_y(cs, b, &left)) | ||
363 | }, | 416 | }, |
364 | } | 417 | } |
418 | + }; | ||
365 | 419 | ||
366 | - match r.1 { | ||
367 | - None => {}, | ||
368 | - Some(a) => { | ||
369 | - println!("== r: [{:?}] - {:?}", r, cs[a]); | ||
370 | - r_edge.append(&mut walk_edge(cs[r.0], cs[a])); | ||
371 | - r = (a, next_y(cs, a, &right)); | ||
372 | - } | ||
373 | - } | 420 | + while l.1 != None || r.1 != None { |
421 | + l = append_edge(&mut l_edge, &l); | ||
422 | + r = append_edge(&mut r_edge, &r); | ||
374 | } | 423 | } |
375 | 424 | ||
376 | println!("== [{}] {:?}", l_edge.len(), l_edge); | 425 | println!("== [{}] {:?}", l_edge.len(), l_edge); |
@@ -379,11 +379,11 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | @@ -379,11 +379,11 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
379 | None | 379 | None |
380 | }}; | 380 | }}; |
381 | 381 | ||
382 | - let ps :Vec<(Polygon<T>, u32)> = self.faces.iter() | 382 | + let mut ps :Vec<(Polygon<T>, u32)> = self.faces.iter() |
383 | . filter_map(to_poly).collect(); | 383 | . filter_map(to_poly).collect(); |
384 | // this sorts by the color value which is no longer neccessary as soon | 384 | // this sorts by the color value which is no longer neccessary as soon |
385 | // as the z-buffer is complete. | 385 | // as the z-buffer is complete. |
386 | - // ps.sort_by(|a, b| a.1.cmp(&b.1)); | 386 | + ps.sort_by(|a, b| a.1.cmp(&b.1)); |
387 | ps | 387 | ps |
388 | } | 388 | } |
389 | } | 389 | } |
Please
register
or
login
to post a comment