rust/integral-geometry/src/lib.rs
author unc0rr
Wed, 17 Oct 2018 22:45:33 +0200
changeset 13935 75eaf7c71789
child 13937 7f1c178506bb
permissions -rw-r--r--
Introduce integral-geometry crate, implement LinePoints iterator
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
13935
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
     1
use std::cmp;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
     2
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
     3
pub struct LinePoints {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
     4
    e_x: i32,
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
     5
    e_y: i32,
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
     6
    d_x: i32,
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
     7
    d_y: i32,
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
     8
    s_x: i32,
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
     9
    s_y: i32,
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    10
    x: i32,
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    11
    y: i32,
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    12
    d: i32,
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    13
    i: i32,
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    14
}
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    15
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    16
impl LinePoints {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    17
    pub fn new(x1: i32, y1: i32, x2: i32, y2: i32) -> Self {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    18
        let mut d_x: i32 = x2 - x1;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    19
        let mut d_y: i32 = y2 - y1;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    20
        let s_x: i32;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    21
        let s_y: i32;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    22
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    23
        if d_x > 0 {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    24
            s_x = 1;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    25
        } else if d_x < 0 {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    26
            s_x = -1;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    27
            d_x = -d_x;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    28
        } else {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    29
            s_x = d_x;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    30
        }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    31
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    32
        if d_y > 0 {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    33
            s_y = 1;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    34
        } else if d_y < 0 {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    35
            s_y = -1;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    36
            d_y = -d_y;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    37
        } else {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    38
            s_y = d_y;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    39
        }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    40
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    41
        Self {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    42
            e_x: 0,
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    43
            e_y: 0,
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    44
            d_x,
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    45
            d_y,
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    46
            s_x,
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    47
            s_y,
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    48
            x: x1,
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    49
            y: y1,
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    50
            d: cmp::max(d_x, d_y),
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    51
            i: 0,
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    52
        }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    53
    }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    54
}
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    55
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    56
impl Iterator for LinePoints {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    57
    type Item = (i32, i32);
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    58
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    59
    fn next(&mut self) -> Option<Self::Item> {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    60
        if self.i <= self.d {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    61
            self.e_x += self.d_x;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    62
            self.e_y += self.d_y;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    63
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    64
            if self.e_x > self.d {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    65
                self.e_x -= self.d;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    66
                self.x += self.s_x;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    67
            }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    68
            if self.e_y > self.d {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    69
                self.e_y -= self.d;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    70
                self.y += self.s_y;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    71
            }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    72
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    73
            self.i += 1;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    74
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    75
            Some((self.x, self.y))
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    76
        } else {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    77
            None
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    78
        }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    79
    }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    80
}
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    81
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    82
#[cfg(test)]
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    83
mod tests {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    84
    use super::*;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    85
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    86
    #[test]
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    87
    fn basic() {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    88
        let v = vec![(0, 0), (1, 1), (2, 2), (3, 3)];
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    89
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    90
        for (&a, b) in v.iter().zip(LinePoints::new(0, 0, 3, 3)) {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    91
            assert_eq!(a, b);
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    92
        }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    93
    }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
    94
}