rust/integral-geometry/src/lib.rs
changeset 13962 3f69a70063a5
parent 13959 1fa905aa4cdb
child 13963 7e7a03e85ac4
equal deleted inserted replaced
13961:1c30793b1cea 13962:3f69a70063a5
     1 use std::cmp;
     1 use std::cmp;
     2 use std::ops::{Add, Sub, Mul, Div, AddAssign, SubAssign, MulAssign, DivAssign};
     2 use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
     3 
     3 
     4 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
     4 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
     5 pub struct Point {
     5 pub struct Point {
     6     pub x: i32,
     6     pub x: i32,
     7     pub y: i32,
     7     pub y: i32,
     8 }
     8 }
     9 
     9 
    10 impl Point {
    10 impl Point {
    11     #[inline]
    11     #[inline]
    12     pub fn new(x: i32, y: i32) -> Self {
    12     pub fn new(x: i32, y: i32) -> Self {
    13         Self {x, y}
    13         Self { x, y }
    14     }
    14     }
    15 
    15 
    16     #[inline]
    16     #[inline]
    17     pub fn zero() -> Self {
    17     pub fn zero() -> Self {
    18         Self::new(0, 0)
    18         Self::new(0, 0)
    44         impl $op for Point {
    44         impl $op for Point {
    45             type Output = Self;
    45             type Output = Self;
    46 
    46 
    47             #[inline]
    47             #[inline]
    48             fn $name(self, rhs: Self) -> Self::Output {
    48             fn $name(self, rhs: Self) -> Self::Output {
    49                 Self::new(self.x.$name(rhs.x),
    49                 Self::new(self.x.$name(rhs.x), self.y.$name(rhs.y))
    50                           self.y.$name(rhs.y))
    50             }
    51             }
    51         }
    52         }
    52     };
    53     }
       
    54 }
    53 }
    55 
    54 
    56 macro_rules! bin_assign_op_impl {
    55 macro_rules! bin_assign_op_impl {
    57     ($op: ty, $name: tt) => {
    56     ($op: ty, $name: tt) => {
    58         impl $op for Point {
    57         impl $op for Point {
    59             #[inline]
    58             #[inline]
    60             fn $name(&mut self, rhs: Self){
    59             fn $name(&mut self, rhs: Self) {
    61                 self.x.$name(rhs.x);
    60                 self.x.$name(rhs.x);
    62                 self.y.$name(rhs.y);
    61                 self.y.$name(rhs.y);
    63             }
    62             }
    64         }
    63         }
    65     }
    64     };
    66 }
    65 }
    67 
    66 
    68 bin_op_impl!(Add, add);
    67 bin_op_impl!(Add, add);
    69 bin_op_impl!(Sub, sub);
    68 bin_op_impl!(Sub, sub);
    70 bin_op_impl!(Mul, mul);
    69 bin_op_impl!(Mul, mul);
   121             None
   120             None
   122         }
   121         }
   123     }
   122     }
   124 }
   123 }
   125 
   124 
       
   125 pub struct ArcPoints {
       
   126     point: Point,
       
   127     step: i32,
       
   128 }
       
   129 
       
   130 impl ArcPoints {
       
   131     pub fn new(radius: i32) -> Self {
       
   132         Self {
       
   133             point: Point::new(0, radius),
       
   134             step: 3 - 2 * radius,
       
   135         }
       
   136     }
       
   137 }
       
   138 
       
   139 impl Iterator for ArcPoints {
       
   140     type Item = Point;
       
   141 
       
   142     fn next(&mut self) -> Option<Self::Item> {
       
   143         if self.point.x < self.point.y {
       
   144             let result = self.point;
       
   145 
       
   146             if self.step < 0 {
       
   147                 self.step += self.point.x * 4 + 6;
       
   148             } else {
       
   149                 self.step += (self.point.x - self.point.y) * 4 + 10;
       
   150                 self.point.y -= 1;
       
   151             }
       
   152 
       
   153             self.point.x += 1;
       
   154 
       
   155             Some(result)
       
   156         } else if self.point.x == self.point.y {
       
   157             Some(self.point)
       
   158         } else {
       
   159             None
       
   160         }
       
   161     }
       
   162 }
       
   163 
   126 #[cfg(test)]
   164 #[cfg(test)]
   127 mod tests {
   165 mod tests {
   128     use super::*;
   166     use super::*;
   129 
   167 
   130     fn get_points(coords: &[(i32, i32)]) -> Vec<Point> {
   168     fn get_points(coords: &[(i32, i32)]) -> Vec<Point> {
   142     }
   180     }
   143 
   181 
   144     #[test]
   182     #[test]
   145     fn skewed() {
   183     fn skewed() {
   146         let line = LinePoints::new(Point::new(0, 0), Point::new(5, -7));
   184         let line = LinePoints::new(Point::new(0, 0), Point::new(5, -7));
   147         let v = get_points(&[(0, 0), (1, -1), (2, -2), (2, -3), (3, -4), (4, -5), (4, -6), (5, -7)]);
   185         let v = get_points(&[
       
   186             (0, 0),
       
   187             (1, -1),
       
   188             (2, -2),
       
   189             (2, -3),
       
   190             (3, -4),
       
   191             (4, -5),
       
   192             (4, -6),
       
   193             (5, -7),
       
   194         ]);
   148 
   195 
   149         for (&a, b) in v.iter().zip(line) {
   196         for (&a, b) in v.iter().zip(line) {
   150             assert_eq!(a, b);
   197             assert_eq!(a, b);
   151         }
   198         }
   152     }
   199     }