Commit c99cc1eea0a7fe02152348abb0b5725432181a46

Authored by Georg Hopp
1 parent 8108c69c

Add tail recursice bresenham line

Showing 1 changed file with 51 additions and 1 deletions
... ... @@ -18,10 +18,11 @@
18 18 // You should have received a copy of the GNU General Public License
19 19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 20 //
  21 +use std::cmp;
21 22 use std::convert::{TryFrom, TryInto, Into};
22   -use std::num::TryFromIntError;
23 23 use std::f64::consts::PI as FPI;
24 24 use std::fmt::Display;
  25 +use std::num::TryFromIntError;
25 26 use std::ops::{Add,Sub,Neg,Mul,Div};
26 27
27 28 use fractional::continuous::Continuous;
... ... @@ -30,6 +31,42 @@ use fractional::trigonometry::Trig;
30 31 use fractional::vector::{Vector};
31 32 use fractional::transform::{translate, rotate_x, rotate_y, rotate_z, rotate_v};
32 33
  34 +// Tail recursive Bresenham line with integer incremental error.
  35 +fn line(a :(u32, u32), b :(u32, u32)) -> Vec<(u32, u32)>{
  36 + fn inner( v :&mut [(u32, u32)]
  37 + , bx :u32, by :u32
  38 + , dx :i32, dy :i32
  39 + , sx :i32, sy :i32
  40 + , err :i32) {
  41 + let (x, y) = v[0];
  42 +
  43 + if x != bx || y != by {
  44 + let (x, y, err) = match (2*err as i32 >= dy, 2*err as i32 <= dx) {
  45 + (true, false) => ((x as i32 + sx) as u32, y, err + dy),
  46 + (false, true) => (x, (y as i32 + sy) as u32, err + dx),
  47 + _ => ( (x as i32 + sx) as u32
  48 + , (y as i32 + sy) as u32
  49 + , err + dx + dy ),
  50 + };
  51 + v[1] = (x, y);
  52 + inner(&mut v[1..], bx, by, dx, dy, sx, sy, err);
  53 + }
  54 + }
  55 +
  56 + let (ax, ay) = a;
  57 + let (bx, by) = b;
  58 +
  59 + let dx = (bx as i32 - ax as i32).abs();
  60 + let sx :i32 = if ax < bx { 1 } else { -1 };
  61 + let dy = -(by as i32 - ay as i32).abs();
  62 + let sy :i32 = if ay < by { 1 } else { -1 };
  63 +
  64 + let mut v :Vec<(u32, u32)> = vec!((0, 0); cmp::max(dx, -dy) as usize + 1);
  65 + v[0] = (ax, ay);
  66 + inner(&mut v, bx, by, dx, dy, sx, sy, dx + dy);
  67 + v
  68 +}
  69 +
33 70 fn mean(v: &Vec<i64>) -> Result<Fractional, TryFromIntError> {
34 71 let r = v.iter().fold(0, |acc, x| acc + x);
35 72 let l = i64::try_from(v.len())?;
... ... @@ -235,6 +272,17 @@ fn _transform<T>(v :Vector<T>, v1 :Vector<T>, v2 :Vector<T>, v3 :Vector<T>)
235 272 }
236 273 }
237 274
  275 +fn _line() {
  276 + println!("{:>14} : {:?}", "Line", line((0,1), (6,4)));
  277 + println!("{:>14} : {:?}", "Line", line((0,4), (6,1)));
  278 + println!("{:>14} : {:?}", "Line", line((6,1), (0,4)));
  279 + println!("{:>14} : {:?}", "Line", line((6,4), (0,1)));
  280 + println!("{:>14} : {:?}", "Line", line((0,1), (6,8)));
  281 + println!("{:>14} : {:?}", "Line", line((0,8), (6,1)));
  282 + println!("{:>14} : {:?}", "Line", line((6,1), (0,8)));
  283 + println!("{:>14} : {:?}", "Line", line((6,8), (0,1)));
  284 +}
  285 +
238 286 fn main() {
239 287 common_fractional();
240 288 println!();
... ... @@ -257,4 +305,6 @@ fn main() {
257 305 _transform1();
258 306 println!();
259 307 _transform2();
  308 + println!();
  309 + _line();
260 310 }
... ...
Please register or login to post a comment