Showing
2 changed files
with
90 additions
and
47 deletions
| @@ -262,19 +262,21 @@ enum Direction { Left, Right } | @@ -262,19 +262,21 @@ enum Direction { Left, Right } | ||
| 262 | pub struct Polygon<T>(pub Coordinates<T>); | 262 | pub struct Polygon<T>(pub Coordinates<T>); |
| 263 | 263 | ||
| 264 | #[derive(Debug, Clone)] | 264 | #[derive(Debug, Clone)] |
| 265 | +enum VertexIteratorMode { Vertex, Edge } | ||
| 266 | +#[derive(Debug, Clone)] | ||
| 265 | pub struct VertexIterator<'a,T> where T: Debug { | 267 | pub struct VertexIterator<'a,T> where T: Debug { |
| 266 | p :&'a Polygon<T>, | 268 | p :&'a Polygon<T>, |
| 267 | top :usize, | 269 | top :usize, |
| 268 | current :Option<usize>, | 270 | current :Option<usize>, |
| 269 | edge :Option<LineIterator<T>>, | 271 | edge :Option<LineIterator<T>>, |
| 272 | + mode :VertexIteratorMode, | ||
| 270 | direction :Direction, | 273 | direction :Direction, |
| 271 | } | 274 | } |
| 272 | 275 | ||
| 273 | impl<'a,T> VertexIterator<'a,T> | 276 | impl<'a,T> VertexIterator<'a,T> |
| 274 | where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | 277 | where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> |
| 275 | + Debug + Copy + From<i32> { | 278 | + Debug + Copy + From<i32> { |
| 276 | - | ||
| 277 | - fn new(p :&'a Polygon<T>, direction :Direction) -> Self { | 279 | + fn edge(p :&'a Polygon<T>, direction :Direction) -> Self { |
| 278 | let top = p.vert_min(direction); | 280 | let top = p.vert_min(direction); |
| 279 | let next = p.next_y(top, direction); | 281 | let next = p.next_y(top, direction); |
| 280 | let edge = match next { | 282 | let edge = match next { |
| @@ -286,6 +288,19 @@ where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | @@ -286,6 +288,19 @@ where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | ||
| 286 | , top: top | 288 | , top: top |
| 287 | , current: next | 289 | , current: next |
| 288 | , edge: edge | 290 | , edge: edge |
| 291 | + , mode: VertexIteratorMode::Edge | ||
| 292 | + , direction: direction } | ||
| 293 | + } | ||
| 294 | + | ||
| 295 | + fn vertex(p :&'a Polygon<T>, direction :Direction) -> Self { | ||
| 296 | + let top = p.vert_min(direction); | ||
| 297 | + let next = p.next_y(top, direction); | ||
| 298 | + | ||
| 299 | + VertexIterator { p: p | ||
| 300 | + , top: top | ||
| 301 | + , current: next | ||
| 302 | + , edge: None | ||
| 303 | + , mode: VertexIteratorMode::Vertex | ||
| 289 | , direction: direction } | 304 | , direction: direction } |
| 290 | } | 305 | } |
| 291 | 306 | ||
| @@ -314,14 +329,23 @@ where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | @@ -314,14 +329,23 @@ where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | ||
| 314 | type Item = Coordinate<T>; | 329 | type Item = Coordinate<T>; |
| 315 | 330 | ||
| 316 | fn next(&mut self) -> Option<Self::Item> { | 331 | fn next(&mut self) -> Option<Self::Item> { |
| 317 | - // if for whatever reason edge is "None" finish this iterator. | ||
| 318 | - let next = self.edge.as_mut()?.next(); | ||
| 319 | - | ||
| 320 | - match next { | ||
| 321 | - Some(_) => next, | ||
| 322 | - None => { | ||
| 323 | - self.next_edge()?; | ||
| 324 | - self.next() | 332 | + match self.mode { |
| 333 | + VertexIteratorMode::Edge => { | ||
| 334 | + // if for whatever reason edge is "None" finish this iterator. | ||
| 335 | + let next = self.edge.as_mut()?.next(); | ||
| 336 | + | ||
| 337 | + match next { | ||
| 338 | + Some(_) => next, | ||
| 339 | + None => { | ||
| 340 | + self.next_edge()?; | ||
| 341 | + self.next() | ||
| 342 | + }, | ||
| 343 | + } | ||
| 344 | + }, | ||
| 345 | + VertexIteratorMode::Vertex => { | ||
| 346 | + let current = self.current?; | ||
| 347 | + self.current = self.p.next_y(current, self.direction); | ||
| 348 | + Some(self.p.vertex(current)) | ||
| 325 | }, | 349 | }, |
| 326 | } | 350 | } |
| 327 | } | 351 | } |
| @@ -330,35 +354,56 @@ where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | @@ -330,35 +354,56 @@ where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | ||
| 330 | impl<T> Polygon<T> | 354 | impl<T> Polygon<T> |
| 331 | where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | 355 | where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> |
| 332 | + Copy + Debug + From<i32> { | 356 | + Copy + Debug + From<i32> { |
| 357 | + #[inline] | ||
| 358 | + fn vertex(&self, v :usize) -> Coordinate<T> { | ||
| 359 | + let Polygon(Coordinates(cs)) = self; | ||
| 360 | + cs[v] | ||
| 361 | + } | ||
| 362 | + | ||
| 333 | fn vert_min<'a>(&'a self, d :Direction) -> usize { | 363 | fn vert_min<'a>(&'a self, d :Direction) -> usize { |
| 334 | let Polygon(Coordinates(cs)) = self; | 364 | let Polygon(Coordinates(cs)) = self; |
| 335 | 365 | ||
| 336 | type ICoord<'a,T> = (usize, &'a Coordinate<T>); | 366 | type ICoord<'a,T> = (usize, &'a Coordinate<T>); |
| 337 | 367 | ||
| 338 | - let fold = | acc :Option<ICoord<'a,T>>, x :ICoord<'a,T> | | 368 | + // TODO I guess the problem here is that it does not account for the |
| 369 | + // same y vertex on the beggining and the end. So i guess correct | ||
| 370 | + // would be finding the first one and then dependings on the | ||
| 371 | + // given direction either search left or right for same y's. | ||
| 372 | + let fold = |acc :Option<ICoord<'a,T>>, x :ICoord<'a,T>| | ||
| 339 | match acc { | 373 | match acc { |
| 340 | None => Some(x), | 374 | None => Some(x), |
| 341 | Some(a) => { | 375 | Some(a) => { |
| 342 | let Coordinate(_, ay, _) = a.1; | 376 | let Coordinate(_, ay, _) = a.1; |
| 343 | let Coordinate(_, xy, _) = x.1; | 377 | let Coordinate(_, xy, _) = x.1; |
| 344 | - match d { | ||
| 345 | - Direction::Left => | ||
| 346 | - if xy < ay {Some(x)} else {Some(a)}, | ||
| 347 | - Direction::Right => | ||
| 348 | - if xy <= ay {Some(x)} else {Some(a)}, | ||
| 349 | - } | 378 | + if xy < ay {Some(x)} else {Some(a)} |
| 350 | }, | 379 | }, |
| 351 | }; | 380 | }; |
| 352 | 381 | ||
| 353 | - cs.iter().enumerate().fold(None, fold).unwrap().0 | 382 | + let mut min = cs.iter().enumerate().fold(None, fold).unwrap().0; |
| 383 | + let mut next = self.step(min, d); | ||
| 384 | + | ||
| 385 | + while self.vertex(min).1 == self.vertex(next).1 { | ||
| 386 | + min = next; | ||
| 387 | + next = self.step(min, d); | ||
| 388 | + } | ||
| 389 | + | ||
| 390 | + min | ||
| 391 | + } | ||
| 392 | + | ||
| 393 | + fn left_edge(&self) -> VertexIterator<T> { | ||
| 394 | + VertexIterator::edge(self, Direction::Left) | ||
| 395 | + } | ||
| 396 | + | ||
| 397 | + fn right_edge(&self) -> VertexIterator<T> { | ||
| 398 | + VertexIterator::edge(self, Direction::Right) | ||
| 354 | } | 399 | } |
| 355 | 400 | ||
| 356 | fn left_vertices(&self) -> VertexIterator<T> { | 401 | fn left_vertices(&self) -> VertexIterator<T> { |
| 357 | - VertexIterator::new(self, Direction::Left) | 402 | + VertexIterator::vertex(self, Direction::Left) |
| 358 | } | 403 | } |
| 359 | 404 | ||
| 360 | fn right_vertices(&self) -> VertexIterator<T> { | 405 | fn right_vertices(&self) -> VertexIterator<T> { |
| 361 | - VertexIterator::new(self, Direction::Right) | 406 | + VertexIterator::vertex(self, Direction::Right) |
| 362 | } | 407 | } |
| 363 | 408 | ||
| 364 | fn left(&self, v :usize) -> usize { | 409 | fn left(&self, v :usize) -> usize { |
| @@ -383,12 +428,6 @@ where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | @@ -383,12 +428,6 @@ where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | ||
| 383 | } | 428 | } |
| 384 | } | 429 | } |
| 385 | 430 | ||
| 386 | - #[inline] | ||
| 387 | - fn vertex(&self, v :usize) -> Coordinate<T> { | ||
| 388 | - let Polygon(Coordinates(cs)) = self; | ||
| 389 | - cs[v] | ||
| 390 | - } | ||
| 391 | - | ||
| 392 | fn next_y(&self, c :usize, d :Direction) -> Option<usize> { | 431 | fn next_y(&self, c :usize, d :Direction) -> Option<usize> { |
| 393 | fn inner<T>( p :&Polygon<T> | 432 | fn inner<T>( p :&Polygon<T> |
| 394 | , c :usize | 433 | , c :usize |
| @@ -402,28 +441,30 @@ where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | @@ -402,28 +441,30 @@ where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | ||
| 402 | let Coordinate(_, cy, _) = p.vertex(c); | 441 | let Coordinate(_, cy, _) = p.vertex(c); |
| 403 | let Coordinate(_, ny, _) = p.vertex(n); | 442 | let Coordinate(_, ny, _) = p.vertex(n); |
| 404 | 443 | ||
| 405 | - match ny.cmp(&cy) { | ||
| 406 | - cmp::Ordering::Less => None, | ||
| 407 | - // TODO On equal we need to find out which one of both to | ||
| 408 | - // keep in the list… (the outermost) | ||
| 409 | - // But how can we find the outermost... | ||
| 410 | - // I think it depends on the previous and next one | ||
| 411 | - // which means this might not be best suited for | ||
| 412 | - // a recursive approach...we could keep both... | ||
| 413 | - // Anyway, it looks like this is only a problem | ||
| 414 | - // for the first vertex so maybe it is enough | ||
| 415 | - // to choose the correct one when starting which | ||
| 416 | - // would be in the vert_min method. | ||
| 417 | - // Well, after adding some logic to vert_min it | ||
| 418 | - // seems it is also relevant for the last one. | ||
| 419 | - cmp::Ordering::Equal => inner(p, c, p.step(n, d), d), | ||
| 420 | - cmp::Ordering::Greater => Some(n), | ||
| 421 | - } | 444 | + if ny < cy { None } else { Some(n) } |
| 422 | } | 445 | } |
| 423 | } | 446 | } |
| 424 | 447 | ||
| 425 | inner(self, c, self.step(c, d), d) | 448 | inner(self, c, self.step(c, d), d) |
| 426 | } | 449 | } |
| 450 | + | ||
| 451 | + pub fn debug(&self) { | ||
| 452 | + let mut left = self.left_vertices(); | ||
| 453 | + let mut right = self.right_vertices(); | ||
| 454 | + | ||
| 455 | + if left.find(|l| right.find(|r| l.0 == r.0).is_some()).is_some() { | ||
| 456 | + let left :Vec<Coordinate<T>> = self.left_vertices().collect(); | ||
| 457 | + let right :Vec<Coordinate<T>> = self.right_vertices().collect(); | ||
| 458 | + | ||
| 459 | + println!("==="); | ||
| 460 | + println!("== poly : {:?}", self); | ||
| 461 | + println!("== ltop : {:?}", self.vert_min(Direction::Left)); | ||
| 462 | + println!("== rtop : {:?}", self.vert_min(Direction::Right)); | ||
| 463 | + println!("== left : {:?}", left); | ||
| 464 | + println!("== right : {:?}", right); | ||
| 465 | + println!("==="); | ||
| 466 | + } | ||
| 467 | + } | ||
| 427 | } | 468 | } |
| 428 | 469 | ||
| 429 | impl<T> Drawable<T> for Polygon<T> | 470 | impl<T> Drawable<T> for Polygon<T> |
| @@ -459,7 +500,7 @@ impl<T> Fillable<T> for Polygon<T> | @@ -459,7 +500,7 @@ impl<T> Fillable<T> for Polygon<T> | ||
| 459 | where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | 500 | where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> |
| 460 | + Debug + Clone + Copy + From<i32> { | 501 | + Debug + Clone + Copy + From<i32> { |
| 461 | fn fill(&self, canvas :&mut dyn Canvas<T>, color :u32) { | 502 | fn fill(&self, canvas :&mut dyn Canvas<T>, color :u32) { |
| 462 | - let scanlines = self.left_vertices().zip(self.right_vertices()); | 503 | + let scanlines = self.left_edge().zip(self.right_edge()); |
| 463 | 504 | ||
| 464 | for l in scanlines.flat_map(|(l, r)| l.line_iter(&r)) { | 505 | for l in scanlines.flat_map(|(l, r)| l.line_iter(&r)) { |
| 465 | canvas.set_pixel(l, color); | 506 | canvas.set_pixel(l, color); |
| @@ -342,9 +342,10 @@ fn _democanvas<T>( xcb :&XcbEasel | @@ -342,9 +342,10 @@ fn _democanvas<T>( xcb :&XcbEasel | ||
| 342 | let rot1 = TMatrix::combine(vec!(rz, rx, t)); | 342 | let rot1 = TMatrix::combine(vec!(rz, rx, t)); |
| 343 | let rot2 = TMatrix::combine(vec!(rz, ry, t)); | 343 | let rot2 = TMatrix::combine(vec!(rz, ry, t)); |
| 344 | 344 | ||
| 345 | - let objects = vec!( (tetrahedron.transform(&rot1), 0xFFFF00) ); | ||
| 346 | - //let objects = vec!( (tetrahedron.transform(&rot1), 0xFFFF00) | ||
| 347 | - // , ( cube.transform(&rot2), 0x0000FF) ); | 345 | + let objects = vec!( (tetrahedron.transform(&rot1), 0xFFFF00) |
| 346 | + , ( cube.transform(&rot2), 0x0000FF) ); | ||
| 347 | + //let objects = vec!( ( cube.transform(&rot2), 0x0000FF) ); | ||
| 348 | + //let objects = vec!( (tetrahedron.transform(&rot1), 0xFFFF00) ); | ||
| 348 | //let objects = vec!( (triangle.transform(&rot1), 0xFFFF00) ); | 349 | //let objects = vec!( (triangle.transform(&rot1), 0xFFFF00) ); |
| 349 | 350 | ||
| 350 | <XcbCanvas as Canvas<T>>::clear(&mut canvas); | 351 | <XcbCanvas as Canvas<T>>::clear(&mut canvas); |
| @@ -353,6 +354,7 @@ fn _democanvas<T>( xcb :&XcbEasel | @@ -353,6 +354,7 @@ fn _democanvas<T>( xcb :&XcbEasel | ||
| 353 | for (pg, c) in o.project(&camera, &light, color) { | 354 | for (pg, c) in o.project(&camera, &light, color) { |
| 354 | //canvas.draw(&pg, Coordinate(0, 0, 0.into()), c); | 355 | //canvas.draw(&pg, Coordinate(0, 0, 0.into()), c); |
| 355 | (&pg).fill(&mut canvas, c); | 356 | (&pg).fill(&mut canvas, c); |
| 357 | + //(&pg).debug(); | ||
| 356 | //println!("\n"); | 358 | //println!("\n"); |
| 357 | } | 359 | } |
| 358 | } | 360 | } |
Please
register
or
login
to post a comment