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 | 56 | #[derive(Debug, Clone)] |
57 | 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 | 118 | impl<T> Coordinate<T> |
60 | 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 | 143 | // Tail recursive Bresenham line with integer incremental error. |
63 | 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 | 187 | v |
188 | + */ | |
99 | 189 | } |
100 | 190 | } |
101 | 191 | |
... | ... | @@ -148,7 +238,7 @@ pub struct Line<T>(pub Coordinate<T>, pub Coordinate<T>); |
148 | 238 | |
149 | 239 | impl<T> Drawable<T> for Line<T> |
150 | 240 | where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> |
151 | - + Clone + Copy + From<i32> { | |
241 | + + Debug + Clone + Copy + From<i32> { | |
152 | 242 | fn plot(&self) -> Coordinates<T> { |
153 | 243 | let Line(a, b) = *self; |
154 | 244 | Coordinates(a.line(&b)) |
... | ... | @@ -201,7 +291,7 @@ pub struct Polyline<T>(pub Coordinates<T>); |
201 | 291 | |
202 | 292 | impl<T> Drawable<T> for Polyline<T> |
203 | 293 | where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> |
204 | - + Clone + Copy + From<i32> { | |
294 | + + Debug + Clone + Copy + From<i32> { | |
205 | 295 | fn plot(&self) -> Coordinates<T> { |
206 | 296 | let Polyline(Coordinates(cs)) = self; |
207 | 297 | |
... | ... | @@ -235,7 +325,7 @@ pub struct Polygon<T>(pub Coordinates<T>); |
235 | 325 | |
236 | 326 | impl<T> Drawable<T> for Polygon<T> |
237 | 327 | where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> |
238 | - + Clone + Copy + From<i32> { | |
328 | + + Debug + Clone + Copy + From<i32> { | |
239 | 329 | fn plot(&self) -> Coordinates<T> { |
240 | 330 | let Polygon(Coordinates(cs)) = self; |
241 | 331 | |
... | ... | @@ -267,45 +357,6 @@ where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> |
267 | 357 | + Debug + Clone + Copy + From<i32> { |
268 | 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 | 360 | fn next_y<T>( cs :&[Coordinate<T>] |
310 | 361 | , c :usize |
311 | 362 | , f :&dyn Fn(usize) -> usize) -> Option<usize> { |
... | ... | @@ -353,24 +404,22 @@ where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> |
353 | 404 | let mut l_edge :Vec<Coordinate<T>> = Vec::new(); |
354 | 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 | 425 | println!("== [{}] {:?}", l_edge.len(), l_edge); | ... | ... |
... | ... | @@ -379,11 +379,11 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> |
379 | 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 | 383 | . filter_map(to_poly).collect(); |
384 | 384 | // this sorts by the color value which is no longer neccessary as soon |
385 | 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 | 387 | ps |
388 | 388 | } |
389 | 389 | } | ... | ... |
Please
register
or
login
to post a comment