rust/integral-geometry/src/lib.rs
author alfadur
Sat, 03 Nov 2018 02:21:45 +0300
changeset 14127 5c1ce63114a5
parent 14117 133f648c5fbd
child 14128 6a3bcb7c2981
permissions -rw-r--r--
a bit of simplification
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
14102
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
     1
extern crate fpnum;
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
     2
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
     3
use fpnum::distance;
14113
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
     4
use std::ops::{
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
     5
    Add, AddAssign,
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
     6
    Div, DivAssign,
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
     7
    Mul, MulAssign,
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
     8
    Sub, SubAssign,
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
     9
    RangeInclusive
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
    10
};
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    11
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    12
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    13
pub struct Point {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    14
    pub x: i32,
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    15
    pub y: i32,
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    16
}
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    17
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    18
impl Point {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    19
    #[inline]
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    20
    pub fn new(x: i32, y: i32) -> Self {
13962
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
    21
        Self { x, y }
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    22
    }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    23
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    24
    #[inline]
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    25
    pub fn zero() -> Self {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    26
        Self::new(0, 0)
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    27
    }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    28
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    29
    #[inline]
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    30
    pub fn signum(self) -> Self {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    31
        Self::new(self.x.signum(), self.y.signum())
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    32
    }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    33
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    34
    #[inline]
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    35
    pub fn abs(self) -> Self {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    36
        Self::new(self.x.abs(), self.y.abs())
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    37
    }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    38
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    39
    #[inline]
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    40
    pub fn dot(self, other: Point) -> i32 {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    41
        self.x * other.x + self.y * other.y
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    42
    }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    43
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    44
    #[inline]
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    45
    pub fn max_norm(self) -> i32 {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    46
        std::cmp::max(self.x.abs(), self.y.abs())
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    47
    }
14052
c47283feafac add circle filling to land2d
alfadur
parents: 13971
diff changeset
    48
c47283feafac add circle filling to land2d
alfadur
parents: 13971
diff changeset
    49
    #[inline]
14102
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    50
    pub fn integral_norm(self) -> u32 {
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    51
        distance(self.x, self.y).abs_round()
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    52
    }
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    53
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    54
    #[inline]
14052
c47283feafac add circle filling to land2d
alfadur
parents: 13971
diff changeset
    55
    pub fn transform(self, matrix: &[i32; 4]) -> Self {
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
    56
        Point::new(
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
    57
            matrix[0] * self.x + matrix[1] * self.y,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
    58
            matrix[2] * self.x + matrix[3] * self.y,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
    59
        )
14052
c47283feafac add circle filling to land2d
alfadur
parents: 13971
diff changeset
    60
    }
14127
5c1ce63114a5 a bit of simplification
alfadur
parents: 14117
diff changeset
    61
5c1ce63114a5 a bit of simplification
alfadur
parents: 14117
diff changeset
    62
    #[inline]
5c1ce63114a5 a bit of simplification
alfadur
parents: 14117
diff changeset
    63
    pub fn rotate90(self) -> Self {
5c1ce63114a5 a bit of simplification
alfadur
parents: 14117
diff changeset
    64
        Point::new(-self.y, self.x)
5c1ce63114a5 a bit of simplification
alfadur
parents: 14117
diff changeset
    65
    }
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    66
}
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    67
14053
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    68
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    69
pub struct Size {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    70
    pub width: usize,
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    71
    pub height: usize,
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    72
}
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    73
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    74
impl Size {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    75
    #[inline]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    76
    pub fn new(width: usize, height: usize) -> Self {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    77
        Size { width, height }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    78
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    79
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    80
    #[inline]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    81
    pub fn square(size: usize) -> Self {
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
    82
        Size {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
    83
            width: size,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
    84
            height: size,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
    85
        }
14053
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    86
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    87
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    88
    #[inline]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    89
    pub fn area(&self) -> usize {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    90
        self.width * self.height
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    91
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    92
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    93
    #[inline]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    94
    pub fn linear_index(&self, x: usize, y: usize) -> usize {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    95
        y * self.width + x
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    96
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    97
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    98
    #[inline]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
    99
    pub fn is_power_of_two(&self) -> bool {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   100
        self.width.is_power_of_two() && self.height.is_power_of_two()
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   101
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   102
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   103
    #[inline]
14073
alfadur
parents: 14072 14053
diff changeset
   104
    pub fn next_power_of_two(&self) -> Self {
alfadur
parents: 14072 14053
diff changeset
   105
        Self {
alfadur
parents: 14072 14053
diff changeset
   106
            width: self.width.next_power_of_two(),
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   107
            height: self.height.next_power_of_two(),
14073
alfadur
parents: 14072 14053
diff changeset
   108
        }
alfadur
parents: 14072 14053
diff changeset
   109
    }
alfadur
parents: 14072 14053
diff changeset
   110
alfadur
parents: 14072 14053
diff changeset
   111
    #[inline]
14053
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   112
    pub fn to_mask(&self) -> SizeMask {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   113
        SizeMask::new(*self)
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   114
    }
14080
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   115
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   116
    pub fn to_grid_index(&self) -> GridIndex {
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   117
        GridIndex::new(*self)
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   118
    }
14053
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   119
}
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   120
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   121
pub struct SizeMask {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   122
    size: Size,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   123
}
14053
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   124
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   125
impl SizeMask {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   126
    #[inline]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   127
    pub fn new(size: Size) -> Self {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   128
        assert!(size.is_power_of_two());
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   129
        let size = Size {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   130
            width: !(size.width - 1),
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   131
            height: !(size.height - 1),
14053
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   132
        };
14080
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   133
        Self { size }
14053
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   134
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   135
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   136
    #[inline]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   137
    pub fn contains_x<T: Into<usize>>(&self, x: T) -> bool {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   138
        (self.size.width & x.into()) == 0
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   139
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   140
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   141
    #[inline]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   142
    pub fn contains_y<T: Into<usize>>(&self, y: T) -> bool {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   143
        (self.size.height & y.into()) == 0
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   144
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   145
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   146
    #[inline]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   147
    pub fn contains(&self, point: Point) -> bool {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   148
        self.contains_x(point.x as usize) && self.contains_y(point.y as usize)
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   149
    }
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   150
}
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   151
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   152
pub struct GridIndex {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   153
    shift: Point,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   154
}
14080
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   155
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   156
impl GridIndex {
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   157
    pub fn new(size: Size) -> Self {
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   158
        assert!(size.is_power_of_two());
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   159
        let shift = Point::new(
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   160
            size.width.trailing_zeros() as i32,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   161
            size.height.trailing_zeros() as i32,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   162
        );
14080
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   163
        Self { shift }
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   164
    }
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   165
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   166
    pub fn map(&self, position: Point) -> Point {
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   167
        Point::new(position.x >> self.shift.x, position.y >> self.shift.y)
14080
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   168
    }
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   169
}
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   170
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   171
macro_rules! bin_op_impl {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   172
    ($op: ty, $name: tt) => {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   173
        impl $op for Point {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   174
            type Output = Self;
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   175
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   176
            #[inline]
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   177
            fn $name(self, rhs: Self) -> Self::Output {
13962
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   178
                Self::new(self.x.$name(rhs.x), self.y.$name(rhs.y))
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   179
            }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   180
        }
13962
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   181
    };
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   182
}
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   183
14109
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   184
macro_rules! scalar_bin_op_impl {
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   185
    ($($op: tt)::+, $name: tt) => {
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   186
        impl $($op)::+<i32> for Point {
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   187
            type Output = Self;
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   188
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   189
            #[inline]
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   190
            fn $name(self, rhs: i32) -> Self::Output {
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   191
                Self::new(self.x.$name(rhs), self.y.$name(rhs))
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   192
            }
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   193
        }
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   194
    };
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   195
}
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   196
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   197
macro_rules! bin_assign_op_impl {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   198
    ($op: ty, $name: tt) => {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   199
        impl $op for Point {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   200
            #[inline]
13962
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   201
            fn $name(&mut self, rhs: Self) {
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   202
                self.x.$name(rhs.x);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   203
                self.y.$name(rhs.y);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   204
            }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   205
        }
13962
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   206
    };
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   207
}
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   208
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   209
bin_op_impl!(Add, add);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   210
bin_op_impl!(Sub, sub);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   211
bin_op_impl!(Mul, mul);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   212
bin_op_impl!(Div, div);
14109
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   213
scalar_bin_op_impl!(Mul, mul);
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   214
scalar_bin_op_impl!(Div, div);
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   215
bin_assign_op_impl!(AddAssign, add_assign);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   216
bin_assign_op_impl!(SubAssign, sub_assign);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   217
bin_assign_op_impl!(MulAssign, mul_assign);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   218
bin_assign_op_impl!(DivAssign, div_assign);
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   219
14072
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   220
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   221
pub struct Rect {
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   222
    pub x: i32,
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   223
    pub y: i32,
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   224
    pub width: u32,
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   225
    pub height: u32,
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   226
}
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   227
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   228
impl Rect {
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   229
    #[inline]
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   230
    pub fn new(x: i32, y: i32, width: u32, height: u32) -> Self {
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   231
        Self {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   232
            x,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   233
            y,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   234
            width,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   235
            height,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   236
        }
14072
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   237
    }
14075
3185fb34f3b5 update theme editor to use new land generator implementation
alfadur
parents: 14073
diff changeset
   238
14099
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   239
    pub fn from_box(left: i32, right: i32, top: i32, bottom: i32) -> Self {
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   240
        assert!(left <= right);
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   241
        assert!(top <= bottom);
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   242
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   243
        Rect::new(left, top, (right - left) as u32, (bottom - top) as u32)
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   244
    }
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   245
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   246
    pub fn from_size(top_left: Point, size: Size) -> Self {
14102
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   247
        Rect::new(
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   248
            top_left.x,
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   249
            top_left.y,
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   250
            size.width as u32,
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   251
            size.height as u32,
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   252
        )
14099
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   253
    }
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   254
14117
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   255
    pub fn at_origin(size: Size) -> Self {
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   256
        Rect::from_size(Point::zero(), size)
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   257
    }
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   258
14075
3185fb34f3b5 update theme editor to use new land generator implementation
alfadur
parents: 14073
diff changeset
   259
    #[inline]
3185fb34f3b5 update theme editor to use new land generator implementation
alfadur
parents: 14073
diff changeset
   260
    pub fn size(&self) -> Size {
3185fb34f3b5 update theme editor to use new land generator implementation
alfadur
parents: 14073
diff changeset
   261
        Size::new(self.width as usize, self.height as usize)
3185fb34f3b5 update theme editor to use new land generator implementation
alfadur
parents: 14073
diff changeset
   262
    }
3185fb34f3b5 update theme editor to use new land generator implementation
alfadur
parents: 14073
diff changeset
   263
3185fb34f3b5 update theme editor to use new land generator implementation
alfadur
parents: 14073
diff changeset
   264
    #[inline]
3185fb34f3b5 update theme editor to use new land generator implementation
alfadur
parents: 14073
diff changeset
   265
    pub fn area(&self) -> usize {
3185fb34f3b5 update theme editor to use new land generator implementation
alfadur
parents: 14073
diff changeset
   266
        self.size().area()
3185fb34f3b5 update theme editor to use new land generator implementation
alfadur
parents: 14073
diff changeset
   267
    }
14099
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   268
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   269
    #[inline]
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   270
    pub fn left(&self) -> i32 {
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   271
        self.x
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   272
    }
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   273
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   274
    #[inline]
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   275
    pub fn top(&self) -> i32 {
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   276
        self.y
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   277
    }
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   278
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   279
    #[inline]
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   280
    pub fn right(&self) -> i32 {
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   281
        self.x + self.width as i32
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   282
    }
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   283
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   284
    #[inline]
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   285
    pub fn bottom(&self) -> i32 {
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   286
        self.y + self.height as i32
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   287
    }
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   288
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   289
    #[inline]
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   290
    pub fn top_left(&self) -> Point {
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   291
        Point::new(self.x, self.y)
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   292
    }
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   293
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   294
    #[inline]
14117
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   295
    pub fn bottom_right(&self) -> Point {
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   296
        Point::new(self.right(), self.bottom())
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   297
    }
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   298
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   299
    #[inline]
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   300
    pub fn center(&self) -> Point {
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   301
        (self.top_left() + self.bottom_right()) / 2
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   302
    }
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   303
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   304
    #[inline]
14099
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   305
    pub fn with_margin(&self, margin: i32) -> Self {
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   306
        Rect::from_box(
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   307
            self.left() + margin,
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   308
            self.right() - margin,
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   309
            self.top() + margin,
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   310
            self.bottom() - margin,
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   311
        )
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   312
    }
14102
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   313
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   314
    #[inline]
14113
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   315
    pub fn x_range(&self) -> RangeInclusive<i32> {
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   316
        self.x..=self.x + self.width as i32
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   317
    }
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   318
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   319
    #[inline]
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   320
    pub fn y_range(&self) -> RangeInclusive<i32> {
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   321
        self.y..=self.y + self.height as i32
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   322
    }
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   323
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   324
    /* requires #[feature(range_contains)]
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   325
    #[inline]
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   326
    pub fn contains(&self, point: Point) -> bool {
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   327
        x_range().contains(point.x) && y_range.contains(point.y)
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   328
    }*/
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   329
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   330
    #[inline]
14102
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   331
    pub fn contains_inside(&self, point: Point) -> bool {
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   332
        point.x > self.left()
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   333
            && point.x < self.right()
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   334
            && point.y > self.top()
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   335
            && point.y < self.bottom()
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   336
    }
14113
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   337
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   338
    #[inline]
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   339
    pub fn intersects(&self, other: &Rect) -> bool {
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   340
        self.left() <= self.right()
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   341
            && self.right() >= other.left()
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   342
            && self.top() <= other.bottom()
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   343
            && self.bottom() >= other.top()
32a34bf70f65 add more rectangle methods
alfadur
parents: 14109
diff changeset
   344
    }
14117
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   345
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   346
    #[inline]
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   347
    pub fn split_at(&self, point: Point) -> [Rect; 4] {
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   348
        assert!(self.contains_inside(point));
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   349
        [
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   350
            Rect::from_box(self.left(), point.x, self.top(), point.y),
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   351
            Rect::from_box(point.x, self.right(), self.top(), point.y),
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   352
            Rect::from_box(self.left(), point.x, point.y, self.bottom()),
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   353
            Rect::from_box(point.x, self.right(), point.y, self.bottom())
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   354
        ]
133f648c5fbd add some more rectangle convenience methods
alfadur
parents: 14115
diff changeset
   355
    }
14072
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   356
}
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   357
14115
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   358
pub struct Polygon {
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   359
    vertices: Vec<Point>
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   360
}
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   361
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   362
impl Polygon {
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   363
    pub fn new(vertices: &[Point]) -> Self {
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   364
        let mut v = Vec::with_capacity(vertices.len() + 1);
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   365
        v.extend_from_slice(vertices);
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   366
        if !v.is_empty() {
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   367
            let start = v[0];
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   368
            v.push(start);
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   369
        }
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   370
        Self { vertices: v }
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   371
    }
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   372
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   373
    pub fn edges_count(&self) -> usize {
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   374
        self.vertices.len() - 1
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   375
    }
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   376
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   377
    pub fn get_edge(&self, index: usize) -> Line {
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   378
        Line::new(self.vertices[index], self.vertices[index + 1])
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   379
    }
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   380
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   381
    pub fn iter<'a>(&'a self) -> impl Iterator<Item = Point> + 'a {
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   382
        (&self.vertices[..self.edges_count()]).iter().cloned()
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   383
    }
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   384
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   385
    pub fn iter_edges<'a>(&'a self) -> impl Iterator<Item = Line> + 'a {
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   386
        (&self.vertices[0..self.edges_count()])
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   387
            .iter()
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   388
            .zip(&self.vertices[1..])
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   389
            .map(|(s, e)| Line::new(*s, *e))
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   390
    }
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   391
}
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   392
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   393
impl From<Vec<Point>> for Polygon {
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   394
    fn from(mut v: Vec<Point>) -> Self {
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   395
        if !v.is_empty() && v[0] != v[v.len() - 1] {
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   396
            let start = v[0];
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   397
            v.push(start)
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   398
        }
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   399
        Self { vertices: v }
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   400
    }
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   401
}
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   402
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   403
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   404
pub struct Line {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   405
    pub start: Point,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   406
    pub end: Point,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   407
}
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   408
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   409
impl Line {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   410
    #[inline]
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   411
    pub fn new(start: Point, end: Point) -> Self {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   412
        Self { start, end }
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   413
    }
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   414
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   415
    #[inline]
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   416
    pub fn zero() -> Self {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   417
        Self::new(Point::zero(), Point::zero())
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   418
    }
14098
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   419
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   420
    #[inline]
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   421
    pub fn center(&self) -> Point {
14109
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   422
        (self.start + self.end) / 2
14098
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   423
    }
14127
5c1ce63114a5 a bit of simplification
alfadur
parents: 14117
diff changeset
   424
5c1ce63114a5 a bit of simplification
alfadur
parents: 14117
diff changeset
   425
    #[inline]
5c1ce63114a5 a bit of simplification
alfadur
parents: 14117
diff changeset
   426
    pub fn scaled_normal(&self) -> Point {
5c1ce63114a5 a bit of simplification
alfadur
parents: 14117
diff changeset
   427
        (self.end - self.start).rotate90()
5c1ce63114a5 a bit of simplification
alfadur
parents: 14117
diff changeset
   428
    }
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   429
}
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   430
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   431
impl IntoIterator for Line {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   432
    type Item = Point;
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   433
    type IntoIter = LinePoints;
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   434
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   435
    fn into_iter(self) -> Self::IntoIter {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   436
        LinePoints::new(self)
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   437
    }
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   438
}
14072
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   439
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   440
pub struct LinePoints {
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   441
    accumulator: Point,
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   442
    direction: Point,
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   443
    sign: Point,
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   444
    current: Point,
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   445
    total_steps: i32,
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   446
    step: i32,
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   447
}
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   448
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   449
impl LinePoints {
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   450
    pub fn new(line: Line) -> Self {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   451
        let dir = line.end - line.start;
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   452
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   453
        Self {
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   454
            accumulator: Point::zero(),
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   455
            direction: dir.abs(),
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   456
            sign: dir.signum(),
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   457
            current: line.start,
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   458
            total_steps: dir.max_norm(),
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   459
            step: 0,
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   460
        }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   461
    }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   462
}
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   463
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   464
impl Iterator for LinePoints {
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   465
    type Item = Point;
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   466
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   467
    fn next(&mut self) -> Option<Self::Item> {
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   468
        if self.step <= self.total_steps {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   469
            self.accumulator += self.direction;
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   470
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   471
            if self.accumulator.x > self.total_steps {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   472
                self.accumulator.x -= self.total_steps;
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   473
                self.current.x += self.sign.x;
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   474
            }
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   475
            if self.accumulator.y > self.total_steps {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   476
                self.accumulator.y -= self.total_steps;
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   477
                self.current.y += self.sign.y;
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   478
            }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   479
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   480
            self.step += 1;
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   481
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   482
            Some(self.current)
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   483
        } else {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   484
            None
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   485
        }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   486
    }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   487
}
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   488
13962
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   489
pub struct ArcPoints {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   490
    point: Point,
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   491
    step: i32,
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   492
}
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   493
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   494
impl ArcPoints {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   495
    pub fn new(radius: i32) -> Self {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   496
        Self {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   497
            point: Point::new(0, radius),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   498
            step: 3 - 2 * radius,
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   499
        }
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   500
    }
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   501
}
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   502
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   503
impl Iterator for ArcPoints {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   504
    type Item = Point;
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   505
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   506
    fn next(&mut self) -> Option<Self::Item> {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   507
        if self.point.x < self.point.y {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   508
            let result = self.point;
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   509
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   510
            if self.step < 0 {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   511
                self.step += self.point.x * 4 + 6;
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   512
            } else {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   513
                self.step += (self.point.x - self.point.y) * 4 + 10;
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   514
                self.point.y -= 1;
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   515
            }
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   516
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   517
            self.point.x += 1;
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   518
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   519
            Some(result)
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   520
        } else if self.point.x == self.point.y {
13968
85645992bc8a Fix ArcPoints never finishing
unc0rr
parents: 13964
diff changeset
   521
            self.point.x += 1;
13971
48796bef9e69 Add --protocol option to engine
unc0rr
parents: 13968
diff changeset
   522
13962
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   523
            Some(self.point)
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   524
        } else {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   525
            None
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   526
        }
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   527
    }
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   528
}
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   529
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   530
pub struct EquidistantPoints {
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   531
    vector: Point,
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   532
    iteration: u8,
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   533
}
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   534
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   535
impl EquidistantPoints {
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   536
    pub fn new(vector: Point) -> Self {
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   537
        Self {
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   538
            vector,
13964
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13963
diff changeset
   539
            iteration: if vector.x == vector.y { 4 } else { 8 },
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   540
        }
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   541
    }
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   542
}
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   543
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   544
impl Iterator for EquidistantPoints {
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   545
    type Item = Point;
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   546
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   547
    fn next(&mut self) -> Option<Self::Item> {
13964
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13963
diff changeset
   548
        if self.iteration > 0 {
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   549
            self.vector.x = -self.vector.x;
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   550
            if self.iteration & 1 == 0 {
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   551
                self.vector.y = -self.vector.y;
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   552
            }
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   553
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   554
            if self.iteration == 4 {
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   555
                std::mem::swap(&mut self.vector.x, &mut self.vector.y);
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   556
            }
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   557
13964
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13963
diff changeset
   558
            self.iteration -= 1;
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   559
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   560
            Some(self.vector)
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   561
        } else {
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   562
            None
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   563
        }
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   564
    }
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   565
}
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   566
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   567
#[cfg(test)]
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   568
mod tests {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   569
    use super::*;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   570
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   571
    fn get_points(coords: &[(i32, i32)]) -> Vec<Point> {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   572
        coords.iter().map(|(x, y)| Point::new(*x, *y)).collect()
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   573
    }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   574
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   575
    #[test]
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   576
    fn line_basic() {
14098
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   577
        let line: Vec<Point> = Line::new(Point::new(0, 0), Point::new(3, 3))
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   578
            .into_iter()
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   579
            .collect();
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   580
        let v = get_points(&[(0, 0), (1, 1), (2, 2), (3, 3)]);
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   581
14098
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   582
        assert_eq!(line, v);
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   583
    }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   584
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   585
    #[test]
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   586
    fn line_skewed() {
14098
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   587
        let line: Vec<Point> = Line::new(Point::new(0, 0), Point::new(5, -7))
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   588
            .into_iter()
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   589
            .collect();
13962
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   590
        let v = get_points(&[
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   591
            (0, 0),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   592
            (1, -1),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   593
            (2, -2),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   594
            (2, -3),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   595
            (3, -4),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   596
            (4, -5),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   597
            (4, -6),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   598
            (5, -7),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   599
        ]);
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   600
14098
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   601
        assert_eq!(line, v);
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   602
    }
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   603
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   604
    #[test]
13964
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13963
diff changeset
   605
    fn equidistant_full() {
14098
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   606
        let n: Vec<Point> = EquidistantPoints::new(Point::new(1, 3)).collect();
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   607
        let v = get_points(&[
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   608
            (-1, -3),
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   609
            (1, -3),
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   610
            (-1, 3),
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   611
            (1, 3),
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   612
            (-3, -1),
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   613
            (3, -1),
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   614
            (-3, 1),
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   615
            (3, 1),
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   616
        ]);
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   617
14098
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   618
        assert_eq!(n, v);
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   619
    }
13964
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13963
diff changeset
   620
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13963
diff changeset
   621
    #[test]
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13963
diff changeset
   622
    fn equidistant_half() {
14098
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   623
        let n: Vec<Point> = EquidistantPoints::new(Point::new(2, 2)).collect();
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   624
        let v = get_points(&[(-2, -2), (2, -2), (-2, 2), (2, 2)]);
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   625
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   626
        assert_eq!(n, v);
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   627
    }
13964
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13963
diff changeset
   628
14098
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   629
    #[test]
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   630
    fn line() {
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   631
        let l = Line::new(Point::new(1, 1), Point::new(5, 6));
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   632
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   633
        assert_eq!(l.center(), Point::new(3, 3));
13964
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13963
diff changeset
   634
    }
14099
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   635
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   636
    #[test]
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   637
    fn rect() {
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   638
        let r = Rect::from_box(10, 100, 0, 70);
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   639
14102
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   640
        assert!(r.contains_inside(Point::new(99, 69)));
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   641
        assert!(!r.contains_inside(Point::new(100, 70)));
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   642
14099
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   643
        assert_eq!(r.top_left(), Point::new(10, 0));
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   644
        assert_eq!(r.with_margin(12), Rect::from_box(22, 88, 12, 58));
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   645
    }
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   646
}