Commit 29c366d709d8e31ae0f16d9f2a18b9e7aeab6147

Authored by Georg Hopp
1 parent 8f0edfaa

More iterators

Showing 1 changed file with 190 additions and 166 deletions
... ... @@ -62,8 +62,7 @@ pub struct LineIterator<T> where T: Debug {
62 62 , b :Coordinate<T>
63 63 , dx :i32
64 64 , dy :i32
65   - , dzx :T
66   - , dzy :T
  65 + , dz :T
67 66 , sx :i32
68 67 , sy :i32
69 68 , err :i32
... ... @@ -75,41 +74,43 @@ where T: Add<Output = T> + Debug + Copy + From<i32> {
75 74 type Item = Coordinate<T>;
76 75
77 76 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) }
  77 + match self.a {
  78 + None => None,
  79 + Some(a) => {
  80 + let Coordinate(ax, ay, az) = a;
  81 + let Coordinate(bx, by, _) = self.b;
  82 +
  83 + if ax != bx || ay != by {
  84 + match (2 * self.err >= self.dy, 2 * self.err <= self.dx ) {
  85 + (true, false) => {
  86 + let r = self.a;
  87 + self.a = Some(Coordinate( ax + self.sx
  88 + , ay
  89 + , az + self.dz ));
  90 + self.err = self.err + self.dy;
  91 + if self.only_edges { self.next() } else { r }
  92 + },
  93 + (false, true) => {
  94 + let r = self.a;
  95 + self.a = Some(Coordinate( ax
  96 + , ay + self.sy
  97 + , az + self.dz ));
  98 + self.err = self.err + self.dx;
  99 + r
  100 + },
  101 + _ => {
  102 + let r = self.a;
  103 + self.a = Some(Coordinate( ax + self.sx
  104 + , ay + self.sy
  105 + , az + self.dz ));
  106 + self.err = self.err + self.dx + self.dy;
  107 + r
  108 + },
  109 + }
  110 + } else {
  111 + self.a = None;
  112 + Some(self.b)
  113 + }
113 114 }
114 115 }
115 116 }
... ... @@ -122,17 +123,14 @@ where T: Add<Output = T> + Sub<Output = T> + Div<Output = T>
122 123 let Coordinate(ax, ay, az) = self;
123 124 let Coordinate(bx, by, bz) = *b;
124 125
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();
  126 + let dx = (bx - ax).abs();
  127 + let dy = -(by - ay).abs();
129 128
130 129 LineIterator { a: Some(self)
131 130 , b: *b
132 131 , dx: dx
133 132 , dy: dy
134   - , dzx: if size == dx { dz } else { 0.into() }
135   - , dzy: if size == -dy { dz } else { 0.into() }
  133 + , dz: (bz - az) / cmp::max(dx, -dy).into()
136 134 , sx: if ax < bx { 1 } else { -1 }
137 135 , sy: if ay < by { 1 } else { -1 }
138 136 , err: dx + dy
... ... @@ -140,52 +138,20 @@ where T: Add<Output = T> + Sub<Output = T> + Div<Output = T>
140 138 }
141 139 }
142 140
143   - // Tail recursive Bresenham line with integer incremental error.
  141 + fn line_iter(self, b :&Self) -> LineIterator<T> {
  142 + self.iter(b, false)
  143 + }
  144 +
144 145 fn line(self, b :&Self) -> Vec<Self> {
145   - self.iter(b, false).collect()
  146 + self.line_iter(b).collect()
146 147 }
147 148
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 },
183   - }
184   - }
  149 + fn edge_iter(self, b :&Self) -> LineIterator<T> {
  150 + self.iter(b, true)
  151 + }
185 152
186   - v.push(*b);
187   - v
188   - */
  153 + fn edge(self, b :&Self) -> Vec<Self> {
  154 + self.edge_iter(b).collect()
189 155 }
190 156 }
191 157
... ... @@ -252,40 +218,6 @@ impl<T> Display for Line<T> {
252 218 }
253 219 }
254 220
255   -// In 3D a rectangle is not as trivial as in 2D, it might be somehow rotate
256   -// and thus we need to specify a Z offset for the other two corners.
257   -// As I do not need rectangle at all I just comment out this code for now.
258   -/*
259   -#[derive(Debug, Clone, Copy)]
260   -pub struct Rectangle<T>(pub Coordinate<T>, pub Coordinate<T>);
261   -
262   -impl<T> Drawable<T> for Rectangle<T> {
263   - fn plot(&self) -> Coordinates<T> {
264   - let Rectangle(a, c) = *self;
265   - let Coordinate(ax, ay, az) = a;
266   - let Coordinate(cx, cy, cz) = c;
267   - let b = Coordinate(cx, ay);
268   - let d = Coordinate(ax, cy);
269   -
270   - let mut r = a.line(&b);
271   - r.append(&mut b.line(&c)[1..].to_vec());
272   - r.append(&mut c.line(&d)[1..].to_vec());
273   - let mut i = d.line(&a);
274   - let l = i.len();
275   - r.append(&mut i[1..l-1].to_vec());
276   -
277   - Coordinates(r)
278   - }
279   -}
280   -
281   -impl Display for Rectangle {
282   - fn fmt(&self, f: &mut Formatter<'_>) -> Result {
283   - let Rectangle(a, b) = self;
284   - write!(f, "Rec[{},{}]", a, b)
285   - }
286   -}
287   -*/
288   -
289 221 #[derive(Debug, Clone)]
290 222 pub struct Polyline<T>(pub Coordinates<T>);
291 223
... ... @@ -320,9 +252,126 @@ impl<T> Display for Polyline<T> where T: Copy {
320 252 }
321 253 }
322 254
  255 +#[derive(Debug, Clone, Copy)]
  256 +enum Direction { Left, Right }
  257 +
323 258 #[derive(Debug, Clone)]
324 259 pub struct Polygon<T>(pub Coordinates<T>);
325 260
  261 +#[derive(Debug, Clone)]
  262 +pub struct VertexIterator<'a,T> where T: Debug {
  263 + p :&'a Polygon<T>,
  264 + top :usize,
  265 + current :Option<usize>,
  266 + inner :Option<LineIterator<T>>,
  267 + direction :Direction,
  268 +}
  269 +
  270 +impl<'a,T> Iterator for VertexIterator<'a,T>
  271 +where T: Add<Output = T> + Sub<Output = T> + Div<Output = T>
  272 + + Debug + Copy + From<i32> {
  273 + type Item = Coordinate<T>;
  274 +
  275 + fn next(&mut self) -> Option<Self::Item> {
  276 + let inner = match self.inner {
  277 + Some(i) => i,
  278 + None => {
  279 + let current = self.current?;
  280 + let next = self.p.next_y(current, self.direction)?;
  281 + self.p.vertex(current).edge_iter(&self.p.vertex(next))
  282 + },
  283 + }
  284 +
  285 + match self.current {
  286 + None => None,
  287 + Some(c) => {
  288 + let r = self.p.vertex(c);
  289 + self.current = self.p.next_y(c, self.direction);
  290 + Some(r)
  291 + },
  292 + }
  293 + }
  294 +}
  295 +
  296 +impl<T> Polygon<T> where T: Copy + Debug {
  297 + fn vert_min<'a>(&'a self) -> usize {
  298 + let Polygon(Coordinates(cs)) = self;
  299 +
  300 + type ICoord<'a,T> = (usize, &'a Coordinate<T>);
  301 +
  302 + let fold = | acc :Option<ICoord<'a,T>>, x :ICoord<'a,T> |
  303 + match acc {
  304 + None => Some(x),
  305 + Some(a) => {
  306 + let Coordinate(_, ay, _) = a.1;
  307 + let Coordinate(_, xy, _) = x.1;
  308 + if xy < ay {Some(x)} else {Some(a)}
  309 + },
  310 + };
  311 +
  312 + cs.iter().enumerate().fold(None, fold).unwrap().0
  313 + }
  314 +
  315 + fn left_vertices(&self) -> VertexIterator<T> {
  316 + VertexIterator { p: &self
  317 + , top: self.vert_min()
  318 + , current: Some(self.vert_min())
  319 + , inner: None
  320 + , direction: Direction::Left }
  321 + }
  322 +
  323 + fn left(&self, v :usize) -> usize {
  324 + let Polygon(Coordinates(cs)) = self;
  325 +
  326 + match v {
  327 + 0 => cs.len() - 1,
  328 + _ => v - 1,
  329 + }
  330 + }
  331 +
  332 + fn right(&self, v :usize) -> usize {
  333 + let Polygon(Coordinates(cs)) = self;
  334 +
  335 + (v + 1) % cs.len()
  336 + }
  337 +
  338 + fn step(&self, v :usize, d :Direction) -> usize {
  339 + match d {
  340 + Direction::Left => self.left(v),
  341 + Direction::Right => self.right(v),
  342 + }
  343 + }
  344 +
  345 + #[inline]
  346 + fn vertex(&self, v :usize) -> Coordinate<T> {
  347 + let Polygon(Coordinates(cs)) = self;
  348 + cs[v]
  349 + }
  350 +
  351 + fn next_y(&self, c :usize, d :Direction) -> Option<usize> {
  352 + fn inner<T>( p :&Polygon<T>
  353 + , c :usize
  354 + , n :usize
  355 + , d :Direction) -> Option<usize>
  356 + where T: Copy + Debug {
  357 + if c == n {
  358 + None
  359 + } else {
  360 + let Coordinate(_, cy, _) = p.vertex(c);
  361 + let Coordinate(_, ny, _) = p.vertex(n);
  362 +
  363 + match ny.cmp(&cy) {
  364 + cmp::Ordering::Less => None,
  365 + cmp::Ordering::Equal => inner(p, c, p.step(n, d), d),
  366 + cmp::Ordering::Greater => Some(n),
  367 + }
  368 + }
  369 + }
  370 +
  371 + inner(self, c, self.step(c, d), d)
  372 + }
  373 +}
  374 +
326 375 impl<T> Drawable<T> for Polygon<T>
327 376 where T: Add<Output = T> + Sub<Output = T> + Div<Output = T>
328 377 + Debug + Clone + Copy + From<i32> {
... ... @@ -356,70 +405,45 @@ impl<T> Fillable<T> for Polygon<T>
356 405 where T: Add<Output = T> + Sub<Output = T> + Div<Output = T>
357 406 + Debug + Clone + Copy + From<i32> {
358 407 fn fill(&self) -> Coordinates<T> {
359   -
360   - fn next_y<T>( cs :&[Coordinate<T>]
361   - , c :usize
362   - , f :&dyn Fn(usize) -> usize) -> Option<usize> {
363   - fn inner<T>( cs :&[Coordinate<T>]
364   - , c :usize
365   - , n :usize
366   - , f :&dyn Fn(usize) -> usize) -> Option<usize> {
367   - if c == n {
368   - None
369   - } else {
370   - let Coordinate(_, cy, _) = cs[c];
371   - let Coordinate(_, ny, _) = cs[n];
372   -
373   - match ny.cmp(&cy) {
374   - cmp::Ordering::Less => None,
375   - cmp::Ordering::Equal => inner(cs, c, f(n), f),
376   - cmp::Ordering::Greater => Some(n),
377   - }
378   - }
379   - }
380   -
381   - inner(cs, c, f(c), f)
382   - }
383   -
384 408 let Polygon(Coordinates(cs)) = self;
385 409
386   - let vert_min = cs.iter().enumerate()
387   - . fold( None
388   - , |acc, x| match acc {
389   - None => Some(x),
390   - Some(a) => {
391   - let Coordinate(_, ay, _) = a.1;
392   - let Coordinate(_, xy, _) = x.1;
393   - if xy < ay {Some(x)} else {Some(a)} } } )
394   - . unwrap().0;
395   -
396   - println!("== vert_min: [{:?}] - {:?}", vert_min, cs[vert_min]);
  410 + let vert_min = self.vert_min();
397 411
398   - let right = |x :usize| (x + 1) % cs.len();
399   - let left = |x :usize| if x == 0 { cs.len() - 1 } else { x - 1 };
  412 + println!("== vert_min: [{}] {:?}", vert_min, cs[vert_min]);
400 413
401   - let mut r = (vert_min, next_y(cs, vert_min, &right));
402   - let mut l = (vert_min, next_y(cs, vert_min, &left));
  414 + let mut r = (vert_min, self.next_y(vert_min, Direction::Right));
  415 + let mut l = (vert_min, self.next_y(vert_min, Direction::Left));
403 416
404 417 let mut l_edge :Vec<Coordinate<T>> = Vec::new();
405 418 let mut r_edge :Vec<Coordinate<T>> = Vec::new();
406 419
407 420 let append_edge = | v :&mut Vec<Coordinate<T>>
408   - , e :&(usize, Option<usize>) | {
409   - match *e {
410   - (_, None) => *e,
  421 + , e :(usize, Option<usize>)
  422 + , f :Direction | {
  423 + match e {
  424 + (_, None) => e,
411 425 (a, Some(b)) => {
412   - println!("== l: [{:?}] - {:?}", e, cs[b]);
413 426 let mut edge = cs[a].edge(&cs[b]);
414 427 v.append(&mut edge);
415   - (b, next_y(cs, b, &left))
  428 + (b, self.next_y(b, f))
416 429 },
417 430 }
418 431 };
419 432
  433 + let print_current = |s :&str, e :(usize, Option<usize>)| {
  434 + match e.1 {
  435 + None => println!( "== {}: [{:?}] - {:?}"
  436 + , s, e.1, "None"),
  437 + Some(e) => println!( "== {}: [{:?}] - {:?}"
  438 + , s, e, cs[e]),
  439 + }
  440 + };
  441 +
420 442 while l.1 != None || r.1 != None {
421   - l = append_edge(&mut l_edge, &l);
422   - r = append_edge(&mut r_edge, &r);
  443 + print_current("l", l);
  444 + l = append_edge(&mut l_edge, l, Direction::Left);
  445 + print_current("r", r);
  446 + r = append_edge(&mut r_edge, r, Direction::Right);
423 447 }
424 448
425 449 println!("== [{}] {:?}", l_edge.len(), l_edge);
... ...
Please register or login to post a comment