diff --git a/fractional/src/main.rs b/fractional/src/main.rs
index 7667359..9f2222f 100644
--- a/fractional/src/main.rs
+++ b/fractional/src/main.rs
@@ -18,10 +18,11 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//
+use std::cmp;
use std::convert::{TryFrom, TryInto, Into};
-use std::num::TryFromIntError;
use std::f64::consts::PI as FPI;
use std::fmt::Display;
+use std::num::TryFromIntError;
use std::ops::{Add,Sub,Neg,Mul,Div};
use fractional::continuous::Continuous;
@@ -30,6 +31,42 @@ use fractional::trigonometry::Trig;
use fractional::vector::{Vector};
use fractional::transform::{translate, rotate_x, rotate_y, rotate_z, rotate_v};
+// Tail recursive Bresenham line with integer incremental error.
+fn line(a :(u32, u32), b :(u32, u32)) -> Vec<(u32, u32)>{
+ fn inner( v :&mut [(u32, u32)]
+ , bx :u32, by :u32
+ , dx :i32, dy :i32
+ , sx :i32, sy :i32
+ , err :i32) {
+ let (x, y) = v[0];
+
+ if x != bx || y != by {
+ let (x, y, err) = match (2*err as i32 >= dy, 2*err as i32 <= dx) {
+ (true, false) => ((x as i32 + sx) as u32, y, err + dy),
+ (false, true) => (x, (y as i32 + sy) as u32, err + dx),
+ _ => ( (x as i32 + sx) as u32
+ , (y as i32 + sy) as u32
+ , err + dx + dy ),
+ };
+ v[1] = (x, y);
+ inner(&mut v[1..], bx, by, dx, dy, sx, sy, err);
+ }
+ }
+
+ let (ax, ay) = a;
+ let (bx, by) = b;
+
+ let dx = (bx as i32 - ax as i32).abs();
+ let sx :i32 = if ax < bx { 1 } else { -1 };
+ let dy = -(by as i32 - ay as i32).abs();
+ let sy :i32 = if ay < by { 1 } else { -1 };
+
+ let mut v :Vec<(u32, u32)> = vec!((0, 0); cmp::max(dx, -dy) as usize + 1);
+ v[0] = (ax, ay);
+ inner(&mut v, bx, by, dx, dy, sx, sy, dx + dy);
+ v
+}
+
fn mean(v: &Vec) -> Result {
let r = v.iter().fold(0, |acc, x| acc + x);
let l = i64::try_from(v.len())?;
@@ -235,6 +272,17 @@ fn _transform(v :Vector, v1 :Vector, v2 :Vector, v3 :Vector)
}
}
+fn _line() {
+ println!("{:>14} : {:?}", "Line", line((0,1), (6,4)));
+ println!("{:>14} : {:?}", "Line", line((0,4), (6,1)));
+ println!("{:>14} : {:?}", "Line", line((6,1), (0,4)));
+ println!("{:>14} : {:?}", "Line", line((6,4), (0,1)));
+ println!("{:>14} : {:?}", "Line", line((0,1), (6,8)));
+ println!("{:>14} : {:?}", "Line", line((0,8), (6,1)));
+ println!("{:>14} : {:?}", "Line", line((6,1), (0,8)));
+ println!("{:>14} : {:?}", "Line", line((6,8), (0,1)));
+}
+
fn main() {
common_fractional();
println!();
@@ -257,4 +305,6 @@ fn main() {
_transform1();
println!();
_transform2();
+ println!();
+ _line();
}