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