Commit 56b9b96aa69c4671b857cb24c74e020c052c0ffd

Authored by Georg Hopp
1 parent e5a7533f

fix edge detection

@@ -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