rust/integral-geometry/src/lib.rs
author unC0Rr
Fri, 02 Nov 2018 13:17:46 +0100
changeset 14076 e5904ead4864
parent 14059 c6745a1c827a
child 14077 5ade484f3351
permissions -rw-r--r--
Introduce OutlineSegmentsIterator, some refactoring
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
13941
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
     1
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
     2
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
     3
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
     4
pub struct Point {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
     5
    pub x: i32,
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
     6
    pub y: i32,
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
     7
}
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
     8
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
     9
impl Point {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    10
    #[inline]
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    11
    pub fn new(x: i32, y: i32) -> Self {
13941
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
    12
        Self { x, y }
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    13
    }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    14
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    15
    #[inline]
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    16
    pub fn zero() -> Self {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    17
        Self::new(0, 0)
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    18
    }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    19
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    20
    #[inline]
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    21
    pub fn signum(self) -> Self {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    22
        Self::new(self.x.signum(), self.y.signum())
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    23
    }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    24
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    25
    #[inline]
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    26
    pub fn abs(self) -> Self {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    27
        Self::new(self.x.abs(), self.y.abs())
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    28
    }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    29
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    30
    #[inline]
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    31
    pub fn dot(self, other: Point) -> i32 {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    32
        self.x * other.x + self.y * other.y
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    33
    }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    34
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    35
    #[inline]
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    36
    pub fn max_norm(self) -> i32 {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    37
        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: 13937
diff changeset
    38
    }
14031
c47283feafac add circle filling to land2d
alfadur
parents: 13950
diff changeset
    39
c47283feafac add circle filling to land2d
alfadur
parents: 13950
diff changeset
    40
    #[inline]
c47283feafac add circle filling to land2d
alfadur
parents: 13950
diff changeset
    41
    pub fn transform(self, matrix: &[i32; 4]) -> Self {
14076
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
    42
        Point::new(
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
    43
            matrix[0] * self.x + matrix[1] * self.y,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
    44
            matrix[2] * self.x + matrix[3] * self.y,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
    45
        )
14031
c47283feafac add circle filling to land2d
alfadur
parents: 13950
diff changeset
    46
    }
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    47
}
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
    48
14032
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    49
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    50
pub struct Size {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    51
    pub width: usize,
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    52
    pub height: usize,
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    53
}
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    54
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    55
impl Size {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    56
    #[inline]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    57
    pub fn new(width: usize, height: usize) -> Self {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    58
        Size { width, height }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    59
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    60
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    61
    #[inline]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    62
    pub fn square(size: usize) -> Self {
14076
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
    63
        Size {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
    64
            width: size,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
    65
            height: size,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
    66
        }
14032
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    67
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    68
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    69
    #[inline]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    70
    pub fn area(&self) -> usize {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    71
        self.width * self.height
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    72
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    73
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    74
    #[inline]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    75
    pub fn linear_index(&self, x: usize, y: usize) -> usize {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    76
        y * self.width + x
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    77
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    78
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    79
    #[inline]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    80
    pub fn is_power_of_two(&self) -> bool {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    81
        self.width.is_power_of_two() && self.height.is_power_of_two()
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    82
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    83
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    84
    #[inline]
14052
alfadur
parents: 14051 14032
diff changeset
    85
    pub fn next_power_of_two(&self) -> Self {
alfadur
parents: 14051 14032
diff changeset
    86
        Self {
alfadur
parents: 14051 14032
diff changeset
    87
            width: self.width.next_power_of_two(),
14076
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
    88
            height: self.height.next_power_of_two(),
14052
alfadur
parents: 14051 14032
diff changeset
    89
        }
alfadur
parents: 14051 14032
diff changeset
    90
    }
alfadur
parents: 14051 14032
diff changeset
    91
alfadur
parents: 14051 14032
diff changeset
    92
    #[inline]
14032
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    93
    pub fn to_mask(&self) -> SizeMask {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    94
        SizeMask::new(*self)
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
    95
    }
14059
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14054
diff changeset
    96
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14054
diff changeset
    97
    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: 14054
diff changeset
    98
        GridIndex::new(*self)
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14054
diff changeset
    99
    }
14032
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   100
}
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   101
14076
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   102
pub struct SizeMask {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   103
    size: Size,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   104
}
14032
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   105
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   106
impl SizeMask {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   107
    #[inline]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   108
    pub fn new(size: Size) -> Self {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   109
        assert!(size.is_power_of_two());
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   110
        let size = Size {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   111
            width: !(size.width - 1),
14076
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   112
            height: !(size.height - 1),
14032
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   113
        };
14059
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14054
diff changeset
   114
        Self { size }
14032
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   115
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   116
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   117
    #[inline]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   118
    pub fn contains_x<T: Into<usize>>(&self, x: T) -> bool {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   119
        (self.size.width & x.into()) == 0
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   120
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   121
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   122
    #[inline]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   123
    pub fn contains_y<T: Into<usize>>(&self, y: T) -> bool {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   124
        (self.size.height & y.into()) == 0
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   125
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   126
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   127
    #[inline]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   128
    pub fn contains(&self, point: Point) -> bool {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   129
        self.contains_x(point.x as usize) && self.contains_y(point.y as usize)
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14031
diff changeset
   130
    }
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   131
}
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   132
14076
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   133
pub struct GridIndex {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   134
    shift: Point,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   135
}
14059
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14054
diff changeset
   136
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14054
diff changeset
   137
impl GridIndex {
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14054
diff changeset
   138
    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: 14054
diff changeset
   139
        assert!(size.is_power_of_two());
14076
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   140
        let shift = Point::new(
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   141
            size.width.trailing_zeros() as i32,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   142
            size.height.trailing_zeros() as i32,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   143
        );
14059
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14054
diff changeset
   144
        Self { shift }
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14054
diff changeset
   145
    }
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14054
diff changeset
   146
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14054
diff changeset
   147
    pub fn map(&self, position: Point) -> Point {
14076
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   148
        Point::new(position.x >> self.shift.x, position.y >> self.shift.y)
14059
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14054
diff changeset
   149
    }
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14054
diff changeset
   150
}
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14054
diff changeset
   151
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   152
macro_rules! bin_op_impl {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   153
    ($op: ty, $name: tt) => {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   154
        impl $op for Point {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   155
            type Output = Self;
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   156
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   157
            #[inline]
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   158
            fn $name(self, rhs: Self) -> Self::Output {
13941
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   159
                Self::new(self.x.$name(rhs.x), self.y.$name(rhs.y))
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   160
            }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   161
        }
13941
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   162
    };
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   163
}
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   164
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   165
macro_rules! bin_assign_op_impl {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   166
    ($op: ty, $name: tt) => {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   167
        impl $op for Point {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   168
            #[inline]
13941
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   169
            fn $name(&mut self, rhs: Self) {
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   170
                self.x.$name(rhs.x);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   171
                self.y.$name(rhs.y);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   172
            }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   173
        }
13941
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   174
    };
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   175
}
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   176
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   177
bin_op_impl!(Add, add);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   178
bin_op_impl!(Sub, sub);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   179
bin_op_impl!(Mul, mul);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   180
bin_op_impl!(Div, div);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   181
bin_assign_op_impl!(AddAssign, add_assign);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   182
bin_assign_op_impl!(SubAssign, sub_assign);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   183
bin_assign_op_impl!(MulAssign, mul_assign);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   184
bin_assign_op_impl!(DivAssign, div_assign);
13935
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   185
14051
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13950
diff changeset
   186
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13950
diff changeset
   187
pub struct Rect {
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13950
diff changeset
   188
    pub x: i32,
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13950
diff changeset
   189
    pub y: i32,
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13950
diff changeset
   190
    pub width: u32,
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13950
diff changeset
   191
    pub height: u32,
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13950
diff changeset
   192
}
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13950
diff changeset
   193
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13950
diff changeset
   194
impl Rect {
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13950
diff changeset
   195
    #[inline]
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13950
diff changeset
   196
    pub fn new(x: i32, y: i32, width: u32, height: u32) -> Self {
14076
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   197
        Self {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   198
            x,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   199
            y,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   200
            width,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   201
            height,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   202
        }
14051
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13950
diff changeset
   203
    }
14054
3185fb34f3b5 update theme editor to use new land generator implementation
alfadur
parents: 14052
diff changeset
   204
3185fb34f3b5 update theme editor to use new land generator implementation
alfadur
parents: 14052
diff changeset
   205
    #[inline]
3185fb34f3b5 update theme editor to use new land generator implementation
alfadur
parents: 14052
diff changeset
   206
    pub fn size(&self) -> Size {
3185fb34f3b5 update theme editor to use new land generator implementation
alfadur
parents: 14052
diff changeset
   207
        Size::new(self.width as usize, self.height as usize)
3185fb34f3b5 update theme editor to use new land generator implementation
alfadur
parents: 14052
diff changeset
   208
    }
3185fb34f3b5 update theme editor to use new land generator implementation
alfadur
parents: 14052
diff changeset
   209
3185fb34f3b5 update theme editor to use new land generator implementation
alfadur
parents: 14052
diff changeset
   210
    #[inline]
3185fb34f3b5 update theme editor to use new land generator implementation
alfadur
parents: 14052
diff changeset
   211
    pub fn area(&self) -> usize {
3185fb34f3b5 update theme editor to use new land generator implementation
alfadur
parents: 14052
diff changeset
   212
        self.size().area()
3185fb34f3b5 update theme editor to use new land generator implementation
alfadur
parents: 14052
diff changeset
   213
    }
14051
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13950
diff changeset
   214
}
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13950
diff changeset
   215
14076
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   216
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   217
pub struct Line {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   218
    pub start: Point,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   219
    pub end: Point,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   220
}
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   221
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   222
impl Line {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   223
    #[inline]
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   224
    pub fn new(start: Point, end: Point) -> Self {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   225
        Self { start, end }
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   226
    }
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   227
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   228
    #[inline]
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   229
    pub fn zero() -> Self {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   230
        Self::new(Point::zero(), Point::zero())
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   231
    }
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   232
}
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   233
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   234
impl IntoIterator for Line {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   235
    type Item = Point;
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   236
    type IntoIter = LinePoints;
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   237
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   238
    fn into_iter(self) -> Self::IntoIter {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   239
        LinePoints::new(self)
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   240
    }
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   241
}
14051
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13950
diff changeset
   242
13935
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   243
pub struct LinePoints {
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   244
    accumulator: Point,
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   245
    direction: Point,
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   246
    sign: Point,
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   247
    current: Point,
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   248
    total_steps: i32,
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   249
    step: i32,
13935
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   250
}
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   251
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   252
impl LinePoints {
14076
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   253
    pub fn new(line: Line) -> Self {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   254
        let dir = line.end - line.start;
13935
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   255
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   256
        Self {
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   257
            accumulator: Point::zero(),
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   258
            direction: dir.abs(),
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   259
            sign: dir.signum(),
14076
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   260
            current: line.start,
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   261
            total_steps: dir.max_norm(),
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   262
            step: 0,
13935
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   263
        }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   264
    }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   265
}
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   266
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   267
impl Iterator for LinePoints {
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   268
    type Item = Point;
13935
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   269
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   270
    fn next(&mut self) -> Option<Self::Item> {
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   271
        if self.step <= self.total_steps {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   272
            self.accumulator += self.direction;
13935
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   273
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   274
            if self.accumulator.x > self.total_steps {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   275
                self.accumulator.x -= self.total_steps;
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   276
                self.current.x += self.sign.x;
13935
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   277
            }
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   278
            if self.accumulator.y > self.total_steps {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   279
                self.accumulator.y -= self.total_steps;
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   280
                self.current.y += self.sign.y;
13935
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   281
            }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   282
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   283
            self.step += 1;
13935
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   284
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   285
            Some(self.current)
13935
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   286
        } else {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   287
            None
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   288
        }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   289
    }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   290
}
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   291
13941
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   292
pub struct ArcPoints {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   293
    point: Point,
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   294
    step: i32,
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   295
}
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   296
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   297
impl ArcPoints {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   298
    pub fn new(radius: i32) -> Self {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   299
        Self {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   300
            point: Point::new(0, radius),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   301
            step: 3 - 2 * radius,
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   302
        }
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   303
    }
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   304
}
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   305
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   306
impl Iterator for ArcPoints {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   307
    type Item = Point;
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   308
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   309
    fn next(&mut self) -> Option<Self::Item> {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   310
        if self.point.x < self.point.y {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   311
            let result = self.point;
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   312
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   313
            if self.step < 0 {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   314
                self.step += self.point.x * 4 + 6;
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   315
            } else {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   316
                self.step += (self.point.x - self.point.y) * 4 + 10;
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   317
                self.point.y -= 1;
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   318
            }
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   319
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   320
            self.point.x += 1;
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   321
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   322
            Some(result)
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   323
        } else if self.point.x == self.point.y {
13947
85645992bc8a Fix ArcPoints never finishing
unc0rr
parents: 13943
diff changeset
   324
            self.point.x += 1;
13950
48796bef9e69 Add --protocol option to engine
unc0rr
parents: 13947
diff changeset
   325
13941
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   326
            Some(self.point)
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   327
        } else {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   328
            None
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   329
        }
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   330
    }
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   331
}
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   332
13942
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   333
pub struct EquidistantPoints {
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   334
    vector: Point,
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   335
    iteration: u8,
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   336
}
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   337
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   338
impl EquidistantPoints {
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   339
    pub fn new(vector: Point) -> Self {
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   340
        Self {
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   341
            vector,
13943
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13942
diff changeset
   342
            iteration: if vector.x == vector.y { 4 } else { 8 },
13942
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   343
        }
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   344
    }
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   345
}
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   346
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   347
impl Iterator for EquidistantPoints {
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   348
    type Item = Point;
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   349
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   350
    fn next(&mut self) -> Option<Self::Item> {
13943
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13942
diff changeset
   351
        if self.iteration > 0 {
13942
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   352
            self.vector.x = -self.vector.x;
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   353
            if self.iteration & 1 == 0 {
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   354
                self.vector.y = -self.vector.y;
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   355
            }
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   356
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   357
            if self.iteration == 4 {
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   358
                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: 13941
diff changeset
   359
            }
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   360
13943
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13942
diff changeset
   361
            self.iteration -= 1;
13942
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   362
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   363
            Some(self.vector)
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   364
        } else {
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   365
            None
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   366
        }
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   367
    }
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   368
}
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   369
13935
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   370
#[cfg(test)]
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   371
mod tests {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   372
    use super::*;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   373
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   374
    fn get_points(coords: &[(i32, i32)]) -> Vec<Point> {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   375
        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: 13937
diff changeset
   376
    }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   377
13935
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   378
    #[test]
13942
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   379
    fn line_basic() {
14076
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   380
        let line = Line::new(Point::new(0, 0), Point::new(3, 3)).into_iter();
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   381
        let v = get_points(&[(0, 0), (1, 1), (2, 2), (3, 3), (123, 456)]);
13935
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   382
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   383
        for (&a, b) in v.iter().zip(line) {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   384
            assert_eq!(a, b);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   385
        }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   386
    }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   387
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   388
    #[test]
13942
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   389
    fn line_skewed() {
14076
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14059
diff changeset
   390
        let line = Line::new(Point::new(0, 0), Point::new(5, -7)).into_iter();
13941
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   391
        let v = get_points(&[
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   392
            (0, 0),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   393
            (1, -1),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   394
            (2, -2),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   395
            (2, -3),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   396
            (3, -4),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   397
            (4, -5),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   398
            (4, -6),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   399
            (5, -7),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13938
diff changeset
   400
        ]);
13938
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   401
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13937
diff changeset
   402
        for (&a, b) in v.iter().zip(line) {
13935
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   403
            assert_eq!(a, b);
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   404
        }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   405
    }
13942
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   406
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   407
    #[test]
13943
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13942
diff changeset
   408
    fn equidistant_full() {
13942
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   409
        let n = EquidistantPoints::new(Point::new(1, 3));
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   410
        let v = get_points(&[
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   411
            (-1, -3),
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   412
            (1, -3),
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   413
            (-1, 3),
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   414
            (1, 3),
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   415
            (-3, -1),
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   416
            (3, -1),
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   417
            (-3, 1),
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   418
            (3, 1),
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   419
            (123, 456),
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   420
        ]);
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   421
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   422
        for (&a, b) in v.iter().zip(n) {
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   423
            assert_eq!(a, b);
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   424
        }
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13941
diff changeset
   425
    }
13943
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13942
diff changeset
   426
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13942
diff changeset
   427
    #[test]
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13942
diff changeset
   428
    fn equidistant_half() {
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13942
diff changeset
   429
        let n = EquidistantPoints::new(Point::new(2, 2));
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13942
diff changeset
   430
        let v = get_points(&[(-2, -2), (2, -2), (-2, 2), (2, 2), (123, 456)]);
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13942
diff changeset
   431
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13942
diff changeset
   432
        for (&a, b) in v.iter().zip(n) {
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13942
diff changeset
   433
            assert_eq!(a, b);
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13942
diff changeset
   434
        }
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13942
diff changeset
   435
    }
13935
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   436
}