rust/integral-geometry/src/lib.rs
author S.D.
Tue, 27 Sep 2022 14:59:03 +0300
changeset 15900 fc3cb23fd26f
parent 15850 44b49f255e31
child 15948 9bd828451d77
child 16010 5ba4d3a0c3eb
permissions -rw-r--r--
Allow to see rooms of incompatible versions in the lobby For the new clients the room version is shown in a separate column. There is also a hack for previous versions clients: the room vesion specifier is prepended to the room names for rooms of incompatible versions, and the server shows 'incompatible version' error if the client tries to join them.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
15235
58a0f2a6527b optimize sqrts
alfadur
parents: 15203
diff changeset
     1
use fpnum::{fp, integral_sqrt, FPNum, FPPoint};
14155
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
     2
use std::{
14161
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
     3
    cmp::{max, min},
15046
dc4a12a84c92 remove RangeContains in favor of standard contains
alfadur
parents: 14747
diff changeset
     4
    ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, RangeInclusive, Sub, SubAssign},
14155
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
     5
};
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
     6
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
     7
#[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
     8
pub struct Point {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
     9
    pub x: i32,
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    10
    pub y: i32,
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
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    13
impl Point {
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
    14
    pub const ZERO: Self = Self::new(0, 0);
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
    15
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    16
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
    17
    pub const fn new(x: i32, y: i32) -> Self {
13962
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
    18
        Self { x, y }
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    19
    }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    20
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    21
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
    22
    pub const fn diag(v: i32) -> Self {
14152
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
    23
        Self::new(v, v)
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
    24
    }
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
    25
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
    26
    #[inline]
15773
a4558e2be08c add more const qualifiers to maintain a semblance of activity
alfadur
parents: 15405
diff changeset
    27
    pub const fn signum(self) -> Self {
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    28
        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
    29
    }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    30
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    31
    #[inline]
15773
a4558e2be08c add more const qualifiers to maintain a semblance of activity
alfadur
parents: 15405
diff changeset
    32
    pub const fn abs(self) -> Self {
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    33
        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
    34
    }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    35
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    36
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
    37
    pub const fn dot(self, other: Point) -> i32 {
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    38
        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
    39
    }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    40
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    41
    #[inline]
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
    42
    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
    43
        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
    44
    }
14052
c47283feafac add circle filling to land2d
alfadur
parents: 13971
diff changeset
    45
c47283feafac add circle filling to land2d
alfadur
parents: 13971
diff changeset
    46
    #[inline]
14102
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    47
    pub fn integral_norm(self) -> u32 {
15405
1c6d5656157c ignore overflow in point norm computation
alfadur
parents: 15307
diff changeset
    48
        let sqr = (self.x as u64).wrapping_pow(2) + (self.y as u64).wrapping_pow(2);
15235
58a0f2a6527b optimize sqrts
alfadur
parents: 15203
diff changeset
    49
        integral_sqrt(sqr) as u32
14102
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    50
    }
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    51
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    52
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
    53
    pub const fn transform(self, matrix: &[i32; 4]) -> Self {
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
    54
        Point::new(
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
    55
            matrix[0] * self.x + matrix[1] * self.y,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
    56
            matrix[2] * self.x + matrix[3] * self.y,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
    57
        )
14052
c47283feafac add circle filling to land2d
alfadur
parents: 13971
diff changeset
    58
    }
14127
5c1ce63114a5 a bit of simplification
alfadur
parents: 14117
diff changeset
    59
5c1ce63114a5 a bit of simplification
alfadur
parents: 14117
diff changeset
    60
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
    61
    pub const fn rotate90(self) -> Self {
14128
6a3bcb7c2981 swap coordinate system
alfadur
parents: 14127
diff changeset
    62
        Point::new(self.y, -self.x)
14127
5c1ce63114a5 a bit of simplification
alfadur
parents: 14117
diff changeset
    63
    }
14129
36b792842d5b a bit more simplification
alfadur
parents: 14128
diff changeset
    64
36b792842d5b a bit more simplification
alfadur
parents: 14128
diff changeset
    65
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
    66
    pub const fn cross(self, other: Point) -> i32 {
14129
36b792842d5b a bit more simplification
alfadur
parents: 14128
diff changeset
    67
        self.dot(other.rotate90())
36b792842d5b a bit more simplification
alfadur
parents: 14128
diff changeset
    68
    }
14146
376a0551b00a - Add distance-divider option to land_dump
unc0rr
parents: 14145
diff changeset
    69
376a0551b00a - Add distance-divider option to land_dump
unc0rr
parents: 14145
diff changeset
    70
    #[inline]
14158
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
    71
    pub fn clamp(self, rect: &Rect) -> Point {
14161
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
    72
        Point::new(rect.x_range().clamp(self.x), rect.y_range().clamp(self.y))
14152
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
    73
    }
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
    74
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
    75
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
    76
    pub const fn line_to(self, end: Point) -> Line {
14152
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
    77
        Line::new(self, end)
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
    78
    }
14146
376a0551b00a - Add distance-divider option to land_dump
unc0rr
parents: 14145
diff changeset
    79
14152
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
    80
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
    81
    pub const fn ray_with_dir(self, direction: Point) -> Ray {
14162
477faa7b8a48 fix ray construction
alfadur
parents: 14161
diff changeset
    82
        Ray::new(self, direction)
14152
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
    83
    }
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
    84
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
    85
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
    86
    pub const fn tangent_mul(self, x: i32) -> i32 {
14163
11202097584f fix tangents
alfadur
parents: 14162
diff changeset
    87
        x * self.y / self.x
14152
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
    88
    }
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
    89
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
    90
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
    91
    pub const fn cotangent_mul(self, y: i32) -> i32 {
14163
11202097584f fix tangents
alfadur
parents: 14162
diff changeset
    92
        y * self.x / self.y
14146
376a0551b00a - Add distance-divider option to land_dump
unc0rr
parents: 14145
diff changeset
    93
    }
14160
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
    94
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
    95
    #[inline]
14165
165e43c3ed59 pull land into collision detector
alfadur
parents: 14163
diff changeset
    96
    pub fn to_fppoint(self) -> FPPoint {
14160
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
    97
        FPPoint::new(self.x.into(), self.y.into())
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
    98
    }
14165
165e43c3ed59 pull land into collision detector
alfadur
parents: 14163
diff changeset
    99
165e43c3ed59 pull land into collision detector
alfadur
parents: 14163
diff changeset
   100
    #[inline]
165e43c3ed59 pull land into collision detector
alfadur
parents: 14163
diff changeset
   101
    pub fn from_fppoint(p: &FPPoint) -> Self {
165e43c3ed59 pull land into collision detector
alfadur
parents: 14163
diff changeset
   102
        Self::new(p.x().round(), p.y().round())
165e43c3ed59 pull land into collision detector
alfadur
parents: 14163
diff changeset
   103
    }
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   104
}
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   105
14053
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   106
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   107
pub struct Size {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   108
    pub width: usize,
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   109
    pub height: usize,
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   110
}
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   111
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   112
impl Size {
14738
16024046d458 rescue the atlas
alfadur
parents: 14648
diff changeset
   113
    pub const EMPTY: Self = Self::square(0);
16024046d458 rescue the atlas
alfadur
parents: 14648
diff changeset
   114
14053
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   115
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   116
    pub const fn new(width: usize, height: usize) -> Self {
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   117
        Self { width, height }
14053
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   118
    }
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
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   121
    pub const fn square(size: usize) -> Self {
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   122
        Self {
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   123
            width: size,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   124
            height: size,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   125
        }
14053
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   126
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   127
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   128
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   129
    pub const fn area(&self) -> usize {
14053
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   130
        self.width * self.height
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   131
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   132
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   133
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   134
    pub const fn linear_index(&self, x: usize, y: usize) -> usize {
14053
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   135
        y * self.width + x
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   136
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   137
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   138
    #[inline]
15773
a4558e2be08c add more const qualifiers to maintain a semblance of activity
alfadur
parents: 15405
diff changeset
   139
    pub const fn is_power_of_two(&self) -> bool {
14053
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   140
        self.width.is_power_of_two() && self.height.is_power_of_two()
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   141
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   142
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   143
    #[inline]
15850
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   144
    pub const fn as_power_of_two(&self) -> Option<PotSize> {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   145
        PotSize::new(self.width, self.height)
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   146
    }
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   147
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   148
    #[inline]
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   149
    pub const fn next_power_of_two(&self) -> PotSize {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   150
        PotSize::new_impl(
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   151
            self.width.next_power_of_two(),
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   152
            self.height.next_power_of_two(),
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   153
        )
14073
alfadur
parents: 14072 14053
diff changeset
   154
    }
alfadur
parents: 14072 14053
diff changeset
   155
alfadur
parents: 14072 14053
diff changeset
   156
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   157
    pub const fn transpose(&self) -> Self {
14196
76a52e8149e3 add some texture transforms
alfadur
parents: 14176
diff changeset
   158
        Self::new(self.height, self.width)
76a52e8149e3 add some texture transforms
alfadur
parents: 14176
diff changeset
   159
    }
76a52e8149e3 add some texture transforms
alfadur
parents: 14176
diff changeset
   160
76a52e8149e3 add some texture transforms
alfadur
parents: 14176
diff changeset
   161
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   162
    pub fn to_square(&self) -> Self {
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   163
        Self::square(max(self.width, self.height))
14146
376a0551b00a - Add distance-divider option to land_dump
unc0rr
parents: 14145
diff changeset
   164
    }
376a0551b00a - Add distance-divider option to land_dump
unc0rr
parents: 14145
diff changeset
   165
14738
16024046d458 rescue the atlas
alfadur
parents: 14648
diff changeset
   166
    #[inline]
15773
a4558e2be08c add more const qualifiers to maintain a semblance of activity
alfadur
parents: 15405
diff changeset
   167
    pub const fn contains(&self, other: Self) -> bool {
14738
16024046d458 rescue the atlas
alfadur
parents: 14648
diff changeset
   168
        self.width >= other.width && self.height >= other.height
16024046d458 rescue the atlas
alfadur
parents: 14648
diff changeset
   169
    }
15307
16bd389fc735 ship the atlas to the gpu
alfadur
parents: 15236
diff changeset
   170
16bd389fc735 ship the atlas to the gpu
alfadur
parents: 15236
diff changeset
   171
    #[inline]
16bd389fc735 ship the atlas to the gpu
alfadur
parents: 15236
diff changeset
   172
    pub fn join(&self, other: Self) -> Self {
15850
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   173
        Self::new(max(self.width, other.width), max(self.height, other.height))
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   174
    }
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   175
}
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   176
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   177
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   178
pub struct PotSize {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   179
    size: Size,
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   180
}
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   181
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   182
impl PotSize {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   183
    #[inline]
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   184
    const fn new_impl(width: usize, height: usize) -> Self {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   185
        debug_assert!(width.is_power_of_two() && height.is_power_of_two());
15307
16bd389fc735 ship the atlas to the gpu
alfadur
parents: 15236
diff changeset
   186
        Self {
15850
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   187
            size: Size::new(width, height),
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   188
        }
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   189
    }
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   190
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   191
    #[inline]
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   192
    pub const fn new(width: usize, height: usize) -> Option<Self> {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   193
        if width.is_power_of_two() && height.is_power_of_two() {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   194
            Some(Self::new_impl(width, height))
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   195
        } else {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   196
            None
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   197
        }
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   198
    }
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   199
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   200
    pub const fn size(&self) -> Size {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   201
        self.size
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   202
    }
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   203
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   204
    pub const fn width(&self) -> usize {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   205
        self.size.width
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   206
    }
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   207
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   208
    pub const fn height(&self) -> usize {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   209
        self.size.height
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   210
    }
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   211
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   212
    #[inline]
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   213
    pub const fn square(size: usize) -> Option<Self> {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   214
        if size.is_power_of_two() {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   215
            Some(Self::new_impl(size, size))
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   216
        } else {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   217
            None
15307
16bd389fc735 ship the atlas to the gpu
alfadur
parents: 15236
diff changeset
   218
        }
16bd389fc735 ship the atlas to the gpu
alfadur
parents: 15236
diff changeset
   219
    }
15850
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   220
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   221
    #[inline]
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   222
    pub const fn area(&self) -> usize {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   223
        self.size.area()
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   224
    }
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   225
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   226
    #[inline]
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   227
    pub const fn linear_index(&self, x: usize, y: usize) -> usize {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   228
        self.size.linear_index(x, y)
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   229
    }
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   230
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   231
    #[inline]
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   232
    pub const fn transpose(&self) -> Self {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   233
        Self::new_impl(self.height(), self.width())
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   234
    }
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   235
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   236
    #[inline]
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   237
    pub fn to_square(&self) -> Self {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   238
        let size = max(self.width(), self.height());
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   239
        Self::new_impl(size, size)
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   240
    }
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   241
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   242
    #[inline]
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   243
    pub const fn to_mask(&self) -> SizeMask {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   244
        SizeMask::new(*self)
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   245
    }
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   246
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   247
    pub const fn to_grid_index(&self) -> GridIndex {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   248
        GridIndex::new(*self)
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   249
    }
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   250
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   251
    #[inline]
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   252
    pub const fn contains(&self, other: Self) -> bool {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   253
        self.size.contains(other.size)
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   254
    }
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   255
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   256
    #[inline]
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   257
    pub fn join(&self, other: Self) -> Self {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   258
        Self::new_impl(
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   259
            max(self.width(), other.width()),
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   260
            max(self.height(), other.height()),
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   261
        )
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   262
    }
14053
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   263
}
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   264
14169
d3c9025abd13 seems like about 25% speedup in land filling
alfadur
parents: 14167
diff changeset
   265
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   266
pub struct SizeMask {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   267
    size: Size,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   268
}
14053
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   269
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   270
impl SizeMask {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   271
    #[inline]
15850
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   272
    pub const fn new(size: PotSize) -> Self {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   273
        Self {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   274
            size: Size::new(!(size.width() - 1), !(size.height() - 1)),
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   275
        }
14053
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   276
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   277
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   278
    #[inline]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   279
    pub fn contains_x<T: Into<usize>>(&self, x: T) -> bool {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   280
        (self.size.width & x.into()) == 0
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   281
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   282
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   283
    #[inline]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   284
    pub fn contains_y<T: Into<usize>>(&self, y: T) -> bool {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   285
        (self.size.height & y.into()) == 0
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   286
    }
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   287
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   288
    #[inline]
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   289
    pub fn contains(&self, point: Point) -> bool {
2869c2ccb1b8 extract size struct for common usage
alfadur
parents: 14052
diff changeset
   290
        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
   291
    }
15850
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   292
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   293
    #[inline]
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   294
    pub const fn to_size(&self) -> PotSize {
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   295
        PotSize::new_impl(!self.size.width + 1, !self.size.height + 1)
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   296
    }
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   297
}
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   298
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   299
pub struct GridIndex {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   300
    shift: Point,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   301
}
14080
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   302
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   303
impl GridIndex {
15850
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   304
    pub const fn new(size: PotSize) -> Self {
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   305
        let shift = Point::new(
15850
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   306
            size.width().trailing_zeros() as i32,
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   307
            size.height().trailing_zeros() as i32,
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   308
        );
14080
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   309
        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
   310
    }
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   311
15773
a4558e2be08c add more const qualifiers to maintain a semblance of activity
alfadur
parents: 15405
diff changeset
   312
    pub const fn map(&self, position: Point) -> Point {
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   313
        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
   314
    }
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   315
}
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents: 14075
diff changeset
   316
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   317
macro_rules! bin_op_impl {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   318
    ($op: ty, $name: tt) => {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   319
        impl $op for Point {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   320
            type Output = Self;
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   321
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   322
            #[inline]
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   323
            fn $name(self, rhs: Self) -> Self::Output {
13962
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   324
                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
   325
            }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   326
        }
13962
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   327
    };
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   328
}
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   329
14109
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   330
macro_rules! scalar_bin_op_impl {
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   331
    ($($op: tt)::+, $name: tt) => {
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   332
        impl $($op)::+<i32> for Point {
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   333
            type Output = Self;
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   334
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   335
            #[inline]
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   336
            fn $name(self, rhs: i32) -> Self::Output {
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   337
                Self::new(self.x.$name(rhs), self.y.$name(rhs))
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   338
            }
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   339
        }
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   340
    };
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   341
}
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   342
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   343
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
   344
    ($op: ty, $name: tt) => {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   345
        impl $op for Point {
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   346
            #[inline]
13962
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   347
            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
   348
                self.x.$name(rhs.x);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   349
                self.y.$name(rhs.y);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   350
            }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   351
        }
13962
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   352
    };
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   353
}
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   354
14167
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   355
macro_rules! fp_scalar_bin_op_impl {
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   356
    ($($op: tt)::+, $name: tt) => {
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   357
        impl $($op)::+<FPNum> for Point {
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   358
            type Output = FPPoint;
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   359
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   360
            #[inline]
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   361
            fn $name(self, rhs: FPNum) -> Self::Output {
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   362
                FPPoint::new(rhs.$name(self.x), rhs.$name(self.y))
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   363
            }
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   364
        }
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   365
    };
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   366
}
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   367
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   368
macro_rules! left_fp_scalar_bin_op_impl {
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   369
    ($($op: tt)::+, $name: tt) => {
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   370
        impl $($op)::+<Point> for FPNum {
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   371
            type Output = FPPoint;
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   372
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   373
            #[inline]
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   374
            fn $name(self, rhs: Point) -> Self::Output {
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   375
                FPPoint::new(self.$name(rhs.x), self.$name(rhs.y))
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   376
            }
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   377
        }
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   378
    };
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   379
}
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   380
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   381
bin_op_impl!(Add, add);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   382
bin_op_impl!(Sub, sub);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   383
bin_op_impl!(Mul, mul);
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   384
bin_op_impl!(Div, div);
14109
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   385
scalar_bin_op_impl!(Mul, mul);
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   386
scalar_bin_op_impl!(Div, div);
14167
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   387
fp_scalar_bin_op_impl!(Mul, mul);
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   388
fp_scalar_bin_op_impl!(Div, div);
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   389
left_fp_scalar_bin_op_impl!(Mul, mul);
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   390
left_fp_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
   391
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
   392
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
   393
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
   394
bin_assign_op_impl!(DivAssign, div_assign);
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   395
14072
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   396
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   397
pub struct Rect {
14158
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
   398
    top_left: Point,
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
   399
    bottom_right: Point,
14072
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   400
}
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   401
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   402
impl Rect {
14738
16024046d458 rescue the atlas
alfadur
parents: 14648
diff changeset
   403
    pub const EMPTY: Self = Self {
16024046d458 rescue the atlas
alfadur
parents: 14648
diff changeset
   404
        top_left: Point::ZERO,
14746
19d30d96d7d6 fix atlas.insert
alfadur
parents: 14738
diff changeset
   405
        bottom_right: Point::diag(-1),
14738
16024046d458 rescue the atlas
alfadur
parents: 14648
diff changeset
   406
    };
16024046d458 rescue the atlas
alfadur
parents: 14648
diff changeset
   407
14072
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   408
    #[inline]
15850
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   409
    pub const fn new(top_left: Point, bottom_right: Point) -> Self {
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   410
        debug_assert!(top_left.x <= bottom_right.x + 1);
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   411
        debug_assert!(top_left.y <= bottom_right.y + 1);
14161
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   412
        Self {
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   413
            top_left,
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   414
            bottom_right,
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   415
        }
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   416
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   417
15850
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   418
    pub const fn from_box(left: i32, right: i32, top: i32, bottom: i32) -> Self {
14158
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
   419
        Self::new(Point::new(left, top), Point::new(right, bottom))
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   420
    }
14158
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
   421
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   422
    pub fn from_size(top_left: Point, size: Size) -> Self {
14158
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
   423
        Self::new(
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   424
            top_left,
14161
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   425
            top_left + Point::new(size.width as i32 - 1, size.height as i32 - 1),
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   426
        )
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   427
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   428
14158
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
   429
    pub fn from_size_coords(x: i32, y: i32, width: usize, height: usize) -> Self {
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
   430
        Self::from_size(Point::new(x, y), Size::new(width, height))
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
   431
    }
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
   432
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   433
    pub fn at_origin(size: Size) -> Self {
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   434
        Self::from_size(Point::ZERO, size)
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   435
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   436
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   437
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   438
    pub const fn width(&self) -> usize {
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   439
        (self.right() - self.left() + 1) as usize
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   440
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   441
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   442
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   443
    pub const fn height(&self) -> usize {
14228
bb2f301d4fe0 2018ize everything
alfadur
parents: 14196
diff changeset
   444
        (self.bottom() - self.top() + 1) as usize
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   445
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   446
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   447
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   448
    pub const fn size(&self) -> Size {
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   449
        Size::new(self.width(), self.height())
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   450
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   451
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   452
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   453
    pub const fn area(&self) -> usize {
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   454
        self.size().area()
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   455
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   456
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   457
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   458
    pub const fn left(&self) -> i32 {
14158
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
   459
        self.top_left().x
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   460
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   461
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   462
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   463
    pub const fn top(&self) -> i32 {
14158
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
   464
        self.top_left().y
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   465
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   466
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   467
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   468
    pub const fn right(&self) -> i32 {
14158
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
   469
        self.bottom_right().x
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   470
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   471
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   472
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   473
    pub const fn bottom(&self) -> i32 {
14158
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
   474
        self.bottom_right().y
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   475
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   476
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   477
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   478
    pub const fn top_left(&self) -> Point {
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   479
        self.top_left
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   480
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   481
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   482
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   483
    pub const fn bottom_right(&self) -> Point {
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   484
        self.bottom_right
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   485
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   486
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   487
    #[inline]
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   488
    pub fn center(&self) -> Point {
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   489
        (self.top_left() + self.bottom_right()) / 2
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   490
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   491
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   492
    #[inline]
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   493
    pub fn with_margin(&self, margin: i32) -> Self {
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   494
        let offset = Point::diag(margin);
14161
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   495
        Self::new(self.top_left() + offset, self.bottom_right() - offset)
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   496
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   497
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   498
    #[inline]
15773
a4558e2be08c add more const qualifiers to maintain a semblance of activity
alfadur
parents: 15405
diff changeset
   499
    pub const fn x_range(&self) -> RangeInclusive<i32> {
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   500
        self.left()..=self.right()
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   501
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   502
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   503
    #[inline]
15773
a4558e2be08c add more const qualifiers to maintain a semblance of activity
alfadur
parents: 15405
diff changeset
   504
    pub const fn y_range(&self) -> RangeInclusive<i32> {
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   505
        self.top()..=self.bottom()
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   506
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   507
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   508
    #[inline]
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   509
    pub fn contains(&self, point: Point) -> bool {
15046
dc4a12a84c92 remove RangeContains in favor of standard contains
alfadur
parents: 14747
diff changeset
   510
        self.x_range().contains(&point.x) && self.y_range().contains(&point.y)
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   511
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   512
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   513
    #[inline]
15773
a4558e2be08c add more const qualifiers to maintain a semblance of activity
alfadur
parents: 15405
diff changeset
   514
    pub const fn contains_inside(&self, point: Point) -> bool {
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   515
        point.x > self.left()
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   516
            && point.x < self.right()
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   517
            && point.y > self.top()
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   518
            && point.y < self.bottom()
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   519
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   520
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   521
    #[inline]
14738
16024046d458 rescue the atlas
alfadur
parents: 14648
diff changeset
   522
    pub fn contains_rect(&self, other: &Self) -> bool {
16024046d458 rescue the atlas
alfadur
parents: 14648
diff changeset
   523
        self.contains(other.top_left()) && self.contains(other.bottom_right())
16024046d458 rescue the atlas
alfadur
parents: 14648
diff changeset
   524
    }
16024046d458 rescue the atlas
alfadur
parents: 14648
diff changeset
   525
16024046d458 rescue the atlas
alfadur
parents: 14648
diff changeset
   526
    #[inline]
15773
a4558e2be08c add more const qualifiers to maintain a semblance of activity
alfadur
parents: 15405
diff changeset
   527
    pub const fn intersects(&self, other: &Rect) -> bool {
14747
75ff5c643004 actually atlas tests were also broken
alfadur
parents: 14746
diff changeset
   528
        self.left() <= other.right()
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   529
            && self.right() >= other.left()
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   530
            && self.top() <= other.bottom()
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   531
            && self.bottom() >= other.top()
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   532
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   533
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   534
    #[inline]
15850
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   535
    pub const fn split_at(&self, point: Point) -> [Rect; 4] {
15773
a4558e2be08c add more const qualifiers to maintain a semblance of activity
alfadur
parents: 15405
diff changeset
   536
        debug_assert!(self.contains_inside(point));
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   537
        [
14158
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
   538
            Self::from_box(self.left(), point.x, self.top(), point.y),
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
   539
            Self::from_box(point.x, self.right(), self.top(), point.y),
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
   540
            Self::from_box(point.x, self.right(), point.y, self.bottom()),
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
   541
            Self::from_box(self.left(), point.x, point.y, self.bottom()),
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   542
        ]
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   543
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   544
14158
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
   545
    #[inline]
15850
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15773
diff changeset
   546
    pub const fn with_margins(&self, left: i32, right: i32, top: i32, bottom: i32) -> Self {
14738
16024046d458 rescue the atlas
alfadur
parents: 14648
diff changeset
   547
        Self::from_box(
14746
19d30d96d7d6 fix atlas.insert
alfadur
parents: 14738
diff changeset
   548
            self.left() - left,
14738
16024046d458 rescue the atlas
alfadur
parents: 14648
diff changeset
   549
            self.right() + right,
14746
19d30d96d7d6 fix atlas.insert
alfadur
parents: 14738
diff changeset
   550
            self.top() - top,
14738
16024046d458 rescue the atlas
alfadur
parents: 14648
diff changeset
   551
            self.bottom() + bottom,
16024046d458 rescue the atlas
alfadur
parents: 14648
diff changeset
   552
        )
16024046d458 rescue the atlas
alfadur
parents: 14648
diff changeset
   553
    }
16024046d458 rescue the atlas
alfadur
parents: 14648
diff changeset
   554
16024046d458 rescue the atlas
alfadur
parents: 14648
diff changeset
   555
    #[inline]
14158
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
   556
    pub fn quotient(self, x: usize, y: usize) -> Point {
14161
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   557
        self.top_left() + Point::new((x % self.width()) as i32, (y % self.height()) as i32)
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   558
    }
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   559
}
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
   560
14152
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   561
trait RangeClamp<T> {
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   562
    fn clamp(&self, value: T) -> T;
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   563
}
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   564
14161
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   565
impl<T: Ord + Copy> RangeClamp<T> for RangeInclusive<T> {
14152
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   566
    fn clamp(&self, value: T) -> T {
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   567
        if value < *self.start() {
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   568
            *self.start()
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   569
        } else if value > *self.end() {
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   570
            *self.end()
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   571
        } else {
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   572
            value
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   573
        }
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   574
    }
14072
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   575
}
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   576
14115
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   577
pub struct Polygon {
14146
376a0551b00a - Add distance-divider option to land_dump
unc0rr
parents: 14145
diff changeset
   578
    vertices: Vec<Point>,
14115
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   579
}
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   580
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   581
impl Polygon {
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   582
    pub fn new(vertices: &[Point]) -> Self {
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   583
        let mut v = Vec::with_capacity(vertices.len() + 1);
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   584
        v.extend_from_slice(vertices);
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   585
        if !v.is_empty() {
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   586
            let start = v[0];
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   587
            v.push(start);
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   588
        }
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   589
        Self { vertices: v }
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   590
    }
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   591
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   592
    pub fn edges_count(&self) -> usize {
15236
13041ae61ac5 fix empty polygon iteration
alfadur
parents: 15235
diff changeset
   593
        self.vertices.len().saturating_sub(1)
14115
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   594
    }
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   595
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   596
    pub fn get_edge(&self, index: usize) -> Line {
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   597
        Line::new(self.vertices[index], self.vertices[index + 1])
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   598
    }
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   599
14145
6e0be42d0a8f polygonize OutlinePoints
alfadur
parents: 14133
diff changeset
   600
    pub fn split_edge(&mut self, edge_index: usize, vertex: Point) {
6e0be42d0a8f polygonize OutlinePoints
alfadur
parents: 14133
diff changeset
   601
        self.vertices.insert(edge_index + 1, vertex);
6e0be42d0a8f polygonize OutlinePoints
alfadur
parents: 14133
diff changeset
   602
    }
6e0be42d0a8f polygonize OutlinePoints
alfadur
parents: 14133
diff changeset
   603
6e0be42d0a8f polygonize OutlinePoints
alfadur
parents: 14133
diff changeset
   604
    pub fn iter<'a>(&'a self) -> impl Iterator<Item = &Point> + 'a {
6e0be42d0a8f polygonize OutlinePoints
alfadur
parents: 14133
diff changeset
   605
        (&self.vertices[..self.edges_count()]).iter()
6e0be42d0a8f polygonize OutlinePoints
alfadur
parents: 14133
diff changeset
   606
    }
6e0be42d0a8f polygonize OutlinePoints
alfadur
parents: 14133
diff changeset
   607
14155
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   608
    pub fn iter_mut<'a>(&'a mut self) -> impl Iterator<Item = &mut Point> + 'a {
14176
8f82d87d223f save edges_count
alfadur
parents: 14173
diff changeset
   609
        let edges_count = self.edges_count();
14155
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   610
        let start = self.vertices.as_mut_ptr();
14176
8f82d87d223f save edges_count
alfadur
parents: 14173
diff changeset
   611
        let end = unsafe { start.add(edges_count) };
14161
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   612
        PolygonPointsIteratorMut {
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   613
            source: self,
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   614
            start,
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   615
            end,
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   616
        }
14115
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   617
    }
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   618
14155
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   619
    fn force_close(&mut self) {
14154
a65b60f36b96 fix polygons getting unclosed on mirroring
alfadur
parents: 14152
diff changeset
   620
        if !self.vertices.is_empty() {
14229
87f1054c2333 fix polygon closure
alfadur
parents: 14228
diff changeset
   621
            let edges_count = self.edges_count();
87f1054c2333 fix polygon closure
alfadur
parents: 14228
diff changeset
   622
            self.vertices[edges_count] = self.vertices[0];
14154
a65b60f36b96 fix polygons getting unclosed on mirroring
alfadur
parents: 14152
diff changeset
   623
        }
a65b60f36b96 fix polygons getting unclosed on mirroring
alfadur
parents: 14152
diff changeset
   624
    }
a65b60f36b96 fix polygons getting unclosed on mirroring
alfadur
parents: 14152
diff changeset
   625
14115
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   626
    pub fn iter_edges<'a>(&'a self) -> impl Iterator<Item = Line> + 'a {
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   627
        (&self.vertices[0..self.edges_count()])
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   628
            .iter()
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   629
            .zip(&self.vertices[1..])
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   630
            .map(|(s, e)| Line::new(*s, *e))
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   631
    }
14161
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   632
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   633
    pub fn bezierize(&mut self, segments_number: u32) {
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   634
        fn calc_point(p1: Point, p2: Point, p3: Point) -> FPPoint {
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   635
            let diff13 = (p1 - p3).to_fppoint();
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   636
            let diff13_norm = diff13.distance();
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   637
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   638
            if diff13_norm.is_zero() {
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   639
                diff13
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   640
            } else {
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   641
                let diff12_norm = (p1 - p2).to_fppoint().distance();
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   642
                let diff23_norm = (p2 - p3).to_fppoint().distance();
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   643
                let min_distance = min(diff13_norm, min(diff12_norm, diff23_norm));
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   644
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   645
                diff13 * min_distance / diff13_norm / 3
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   646
            }
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   647
        }
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   648
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   649
        if self.vertices.len() < 4 {
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   650
            return;
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   651
        }
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   652
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   653
        let delta = fp!(1 / segments_number);
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   654
        let mut bezierized_vertices = Vec::new();
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   655
        let mut pi = 0;
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   656
        let mut i = 1;
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   657
        let mut ni = 2;
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   658
        let mut right_point = calc_point(self.vertices[pi], self.vertices[i], self.vertices[ni]);
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   659
        let mut left_point;
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   660
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   661
        pi += 1;
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   662
        while pi != 0 {
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   663
            pi = i;
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   664
            i = ni;
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   665
            ni += 1;
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   666
            if ni >= self.vertices.len() {
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   667
                ni = 0;
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   668
            }
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   669
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   670
            left_point = right_point;
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   671
            right_point = calc_point(self.vertices[pi], self.vertices[i], self.vertices[ni]);
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   672
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   673
            bezierized_vertices.extend(BezierCurveSegments::new(
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   674
                Line::new(self.vertices[pi], self.vertices[i]),
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   675
                left_point,
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   676
                -right_point,
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   677
                delta,
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   678
            ));
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   679
        }
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   680
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   681
        self.vertices = bezierized_vertices;
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   682
    }
14115
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   683
}
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   684
14155
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   685
struct PolygonPointsIteratorMut<'a> {
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   686
    source: &'a mut Polygon,
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   687
    start: *mut Point,
14161
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   688
    end: *mut Point,
14155
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   689
}
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   690
14161
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   691
impl<'a> Iterator for PolygonPointsIteratorMut<'a> {
14155
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   692
    type Item = &'a mut Point;
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   693
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   694
    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   695
        if self.start == self.end {
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   696
            None
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   697
        } else {
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   698
            unsafe {
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   699
                let result = &mut *self.start;
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   700
                self.start = self.start.add(1);
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   701
                Some(result)
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   702
            }
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   703
        }
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   704
    }
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   705
}
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   706
14161
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   707
impl<'a> Drop for PolygonPointsIteratorMut<'a> {
14155
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   708
    fn drop(&mut self) {
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   709
        self.source.force_close();
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   710
    }
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   711
}
09f62bb046ef actually there is a way to preserve mutable polygon iterator
alfadur
parents: 14154
diff changeset
   712
14115
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   713
impl From<Vec<Point>> for Polygon {
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   714
    fn from(mut v: Vec<Point>) -> Self {
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   715
        if !v.is_empty() && v[0] != v[v.len() - 1] {
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   716
            let start = v[0];
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   717
            v.push(start)
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   718
        }
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   719
        Self { vertices: v }
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   720
    }
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   721
}
d0b0d61b7d5e add polygons
alfadur
parents: 14113
diff changeset
   722
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   723
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
14152
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   724
pub struct Ray {
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   725
    pub start: Point,
14161
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   726
    pub direction: Point,
14152
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   727
}
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   728
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   729
impl Ray {
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   730
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   731
    pub const fn new(start: Point, direction: Point) -> Ray {
14152
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   732
        Self { start, direction }
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   733
    }
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   734
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   735
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   736
    pub const fn tangent_mul(&self, x: i32) -> i32 {
14163
11202097584f fix tangents
alfadur
parents: 14162
diff changeset
   737
        self.direction.tangent_mul(x)
14152
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   738
    }
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   739
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   740
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   741
    pub const fn cotangent_mul(&self, y: i32) -> i32 {
14163
11202097584f fix tangents
alfadur
parents: 14162
diff changeset
   742
        self.direction.cotangent_mul(y)
14152
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   743
    }
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   744
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   745
    #[inline]
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   746
    pub fn orientation(&self, point: Point) -> i32 {
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   747
        (point - self.start).cross(self.direction).signum()
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   748
    }
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   749
}
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   750
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   751
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   752
pub struct Line {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   753
    pub start: Point,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   754
    pub end: Point,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   755
}
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   756
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   757
impl Line {
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   758
    pub const ZERO: Self = Self::new(Point::ZERO, Point::ZERO);
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   759
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   760
    #[inline]
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   761
    pub const fn new(start: Point, end: Point) -> Self {
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   762
        Self { start, end }
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   763
    }
14098
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   764
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   765
    #[inline]
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   766
    pub fn center(&self) -> Point {
14109
f483f844da98 component-wise division is actually useful sometimes
alfadur
parents: 14102
diff changeset
   767
        (self.start + self.end) / 2
14098
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   768
    }
14127
5c1ce63114a5 a bit of simplification
alfadur
parents: 14117
diff changeset
   769
5c1ce63114a5 a bit of simplification
alfadur
parents: 14117
diff changeset
   770
    #[inline]
14152
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   771
    pub fn scaled_direction(&self) -> Point {
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   772
        self.end - self.start
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   773
    }
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   774
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   775
    #[inline]
14127
5c1ce63114a5 a bit of simplification
alfadur
parents: 14117
diff changeset
   776
    pub fn scaled_normal(&self) -> Point {
14152
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   777
        self.scaled_direction().rotate90()
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   778
    }
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   779
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   780
    #[inline]
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   781
    pub fn to_ray(&self) -> Ray {
c416d32764b7 organize landgen a bit more
alfadur
parents: 14147
diff changeset
   782
        Ray::new(self.start, self.scaled_direction())
14127
5c1ce63114a5 a bit of simplification
alfadur
parents: 14117
diff changeset
   783
    }
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   784
}
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   785
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   786
impl IntoIterator for Line {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   787
    type Item = Point;
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   788
    type IntoIter = LinePoints;
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   789
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   790
    fn into_iter(self) -> Self::IntoIter {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   791
        LinePoints::new(self)
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   792
    }
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   793
}
14072
8a0d69c16cad Implement OutlinePoints for land generators, some ground work for template based landgen
unc0rr
parents: 13971
diff changeset
   794
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   795
pub struct LinePoints {
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   796
    accumulator: Point,
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   797
    direction: Point,
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   798
    sign: Point,
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   799
    current: Point,
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   800
    total_steps: i32,
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   801
    step: i32,
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   802
}
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   803
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   804
impl LinePoints {
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   805
    pub fn new(line: Line) -> Self {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   806
        let dir = line.end - line.start;
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   807
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   808
        Self {
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   809
            accumulator: Point::ZERO,
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   810
            direction: dir.abs(),
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   811
            sign: dir.signum(),
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14080
diff changeset
   812
            current: line.start,
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   813
            total_steps: dir.max_norm(),
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   814
            step: 0,
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   815
        }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   816
    }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   817
}
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   818
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   819
impl Iterator for LinePoints {
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   820
    type Item = Point;
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   821
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   822
    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
   823
        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
   824
            self.accumulator += self.direction;
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   825
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   826
            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
   827
                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
   828
                self.current.x += self.sign.x;
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   829
            }
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   830
            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
   831
                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
   832
                self.current.y += self.sign.y;
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   833
            }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   834
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   835
            self.step += 1;
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   836
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   837
            Some(self.current)
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   838
        } else {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   839
            None
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   840
        }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   841
    }
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   842
}
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   843
13962
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   844
pub struct ArcPoints {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   845
    point: Point,
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   846
    step: i32,
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   847
}
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   848
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   849
impl ArcPoints {
14648
2e2b31cf0871 make stuff const
alfadur
parents: 14229
diff changeset
   850
    pub const fn new(radius: i32) -> Self {
13962
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   851
        Self {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   852
            point: Point::new(0, radius),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   853
            step: 3 - 2 * radius,
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   854
        }
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   855
    }
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   856
}
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   857
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   858
impl Iterator for ArcPoints {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   859
    type Item = Point;
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   860
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   861
    fn next(&mut self) -> Option<Self::Item> {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   862
        if self.point.x < self.point.y {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   863
            let result = self.point;
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   864
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   865
            if self.step < 0 {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   866
                self.step += self.point.x * 4 + 6;
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   867
            } else {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   868
                self.step += (self.point.x - self.point.y) * 4 + 10;
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   869
                self.point.y -= 1;
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   870
            }
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   871
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   872
            self.point.x += 1;
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   873
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   874
            Some(result)
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   875
        } else if self.point.x == self.point.y {
13968
85645992bc8a Fix ArcPoints never finishing
unc0rr
parents: 13964
diff changeset
   876
            self.point.x += 1;
13971
48796bef9e69 Add --protocol option to engine
unc0rr
parents: 13968
diff changeset
   877
13962
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   878
            Some(self.point)
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   879
        } else {
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   880
            None
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   881
        }
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   882
    }
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   883
}
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
   884
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   885
pub struct EquidistantPoints {
15203
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   886
    vector: Vec<Point>,
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   887
}
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   888
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   889
impl EquidistantPoints {
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   890
    pub fn new(vector: Point) -> Self {
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   891
        Self {
15203
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   892
            vector: if vector.x == vector.y {
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   893
                vec![
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   894
                    Point::new(vector.x, vector.x),
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   895
                    Point::new(vector.x, -vector.x),
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   896
                    Point::new(-vector.x, -vector.x),
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   897
                    Point::new(-vector.x, vector.x),
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   898
                ]
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   899
            } else {
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   900
                vec![
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   901
                    Point::new(vector.x, vector.y),
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   902
                    Point::new(vector.x, -vector.y),
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   903
                    Point::new(-vector.x, -vector.y),
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   904
                    Point::new(-vector.x, vector.y),
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   905
                    Point::new(vector.y, vector.x),
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   906
                    Point::new(vector.y, -vector.x),
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   907
                    Point::new(-vector.y, -vector.x),
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   908
                    Point::new(-vector.y, vector.x),
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   909
                ]
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   910
            },
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   911
        }
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   912
    }
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   913
}
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   914
15203
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   915
impl IntoIterator for EquidistantPoints {
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   916
    type Item = Point;
15203
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   917
    type IntoIter = std::vec::IntoIter<Point>;
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   918
15203
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   919
    fn into_iter(self) -> Self::IntoIter {
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
   920
        self.vector.into_iter()
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   921
    }
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   922
}
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   923
14160
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   924
pub struct BezierCurveSegments {
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   925
    segment: Line,
14167
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   926
    control_point1: FPPoint,
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   927
    control_point2: FPPoint,
14160
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   928
    offset: FPNum,
14161
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   929
    max_offset: FPNum,
14160
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   930
    delta: FPNum,
14161
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   931
    have_finished: bool,
14160
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   932
}
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   933
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   934
impl BezierCurveSegments {
14161
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   935
    pub fn new(segment: Line, p1: FPPoint, p2: FPPoint, delta: FPNum) -> Self {
14160
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   936
        Self {
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   937
            segment,
14167
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   938
            control_point1: segment.start.to_fppoint() - p1,
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   939
            control_point2: segment.end.to_fppoint() - p2,
14160
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   940
            offset: fp!(0),
14161
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   941
            max_offset: fp!(4095 / 4096),
14160
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   942
            delta,
14161
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   943
            have_finished: false,
14160
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   944
        }
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   945
    }
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   946
}
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   947
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   948
impl Iterator for BezierCurveSegments {
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   949
    type Item = Point;
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   950
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   951
    fn next(&mut self) -> Option<Self::Item> {
14161
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   952
        if self.offset < self.max_offset {
14160
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   953
            let offset_sq = self.offset * self.offset;
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   954
            let offset_cub = offset_sq * self.offset;
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   955
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   956
            let r1 = fp!(1) - self.offset * 3 + offset_sq * 3 - offset_cub;
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   957
            let r2 = self.offset * 3 - offset_sq * 6 + offset_cub * 3;
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   958
            let r3 = offset_sq * 3 - offset_cub * 3;
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   959
14167
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   960
            let p = r1 * self.segment.start
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   961
                + r2 * self.control_point1
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   962
                + r3 * self.control_point2
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   963
                + offset_cub * self.segment.end;
14160
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   964
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   965
            self.offset += self.delta;
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   966
14167
4791c9a7d5e8 add more point operators
alfadur
parents: 14165
diff changeset
   967
            Some(Point::from_fppoint(&p))
14161
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   968
        } else if !self.have_finished {
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   969
            self.have_finished = true;
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   970
3078123e84ea Bezierize land outline
unc0rr
parents: 14160
diff changeset
   971
            Some(self.segment.end)
14160
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   972
        } else {
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   973
            None
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   974
        }
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   975
    }
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   976
}
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14158
diff changeset
   977
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   978
#[cfg(test)]
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   979
mod tests {
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   980
    use super::*;
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   981
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   982
    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
   983
        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
   984
    }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   985
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
   986
    #[test]
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   987
    fn line_basic() {
14098
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   988
        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
   989
            .into_iter()
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   990
            .collect();
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   991
        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
   992
14098
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   993
        assert_eq!(line, v);
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   994
    }
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   995
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
   996
    #[test]
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
   997
    fn line_skewed() {
14098
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
   998
        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
   999
            .into_iter()
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
  1000
            .collect();
13962
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
  1001
        let v = get_points(&[
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
  1002
            (0, 0),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
  1003
            (1, -1),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
  1004
            (2, -2),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
  1005
            (2, -3),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
  1006
            (3, -4),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
  1007
            (4, -5),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
  1008
            (4, -6),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
  1009
            (5, -7),
3f69a70063a5 Implement ArcPoints iterator for circles
unc0rr
parents: 13959
diff changeset
  1010
        ]);
13959
1fa905aa4cdb move point struct into integral-geometry and use it to refactor a bit
alfadur
parents: 13958
diff changeset
  1011
14098
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
  1012
        assert_eq!(line, v);
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
  1013
    }
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
  1014
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
  1015
    #[test]
13964
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13963
diff changeset
  1016
    fn equidistant_full() {
15203
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
  1017
        let n: Vec<Point> = EquidistantPoints::new(Point::new(1, 3))
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
  1018
            .into_iter()
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
  1019
            .collect();
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
  1020
        let v = get_points(&[
15203
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
  1021
            (1, 3),
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
  1022
            (1, -3),
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
  1023
            (-1, -3),
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
  1024
            (-1, 3),
15203
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
  1025
            (3, 1),
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
  1026
            (3, -1),
15203
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
  1027
            (-3, -1),
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
  1028
            (-3, 1),
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
  1029
        ]);
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
  1030
14098
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
  1031
        assert_eq!(n, v);
13963
7e7a03e85ac4 Add EquidistantPoints iterator to help iterating over all points of circles
unc0rr
parents: 13962
diff changeset
  1032
    }
13964
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13963
diff changeset
  1033
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13963
diff changeset
  1034
    #[test]
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13963
diff changeset
  1035
    fn equidistant_half() {
15203
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
  1036
        let n: Vec<Point> = EquidistantPoints::new(Point::new(2, 2))
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
  1037
            .into_iter()
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
  1038
            .collect();
decb2f1c682b Rework EquidistantPoints
unc0rr
parents: 15046
diff changeset
  1039
        let v = get_points(&[(2, 2), (2, -2), (-2, -2), (-2, 2)]);
14098
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
  1040
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
  1041
        assert_eq!(n, v);
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
  1042
    }
13964
a325ed57ebfe Don't generate unnecessary duplication in case of equal coordinates
unc0rr
parents: 13963
diff changeset
  1043
14098
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
  1044
    #[test]
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
  1045
    fn line() {
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
  1046
        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
  1047
5ade484f3351 Refactor tests, add fn center() for Line
unC0Rr
parents: 14097
diff changeset
  1048
        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
  1049
    }
14099
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
  1050
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
  1051
    #[test]
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
  1052
    fn rect() {
14158
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
  1053
        let r = Rect::from_box(10, 100, 0, 70);
14099
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
  1054
14102
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
  1055
        assert!(r.contains_inside(Point::new(99, 69)));
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
  1056
        assert!(!r.contains_inside(Point::new(100, 70)));
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
  1057
14099
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
  1058
        assert_eq!(r.top_left(), Point::new(10, 0));
14158
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
  1059
        assert_eq!(r.with_margin(12), Rect::from_box(22, 88, 12, 58));
14099
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
  1060
    }
14146
376a0551b00a - Add distance-divider option to land_dump
unc0rr
parents: 14145
diff changeset
  1061
376a0551b00a - Add distance-divider option to land_dump
unc0rr
parents: 14145
diff changeset
  1062
    #[test]
376a0551b00a - Add distance-divider option to land_dump
unc0rr
parents: 14145
diff changeset
  1063
    fn fit() {
14158
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14156
diff changeset
  1064
        let r = Rect::from_box(10, 100, 0, 70);
14146
376a0551b00a - Add distance-divider option to land_dump
unc0rr
parents: 14145
diff changeset
  1065
14156
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
  1066
        assert_eq!(Point::new(0, -10).clamp(&r), Point::new(10, 0));
7f5a591e1c43 separate rectangle types based on right/bottom edge inclusivity
alfadur
parents: 14155
diff changeset
  1067
        assert_eq!(Point::new(1000, 1000).clamp(&r), Point::new(100, 70));
14146
376a0551b00a - Add distance-divider option to land_dump
unc0rr
parents: 14145
diff changeset
  1068
    }
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents:
diff changeset
  1069
}