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