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