Commit 8f0edfaa14775e387ad3cbf852ce94e90a589790

Authored by Georg Hopp
1 parent 721b89a1

Start making an iterator from the line algorithm

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