rust/landgen/src/outline.rs
author alfadur
Fri, 02 Nov 2018 20:46:17 +0300
changeset 14114 dbaa125a0fe9
parent 14102 5d42204ac35e
child 14116 b2feb190e4bc
permissions -rw-r--r--
fix infinite loop in landgen
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
14090
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
     1
use itertools::Itertools;
14102
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
     2
use std::cmp::min;
14090
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
     3
14099
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
     4
use integral_geometry::{Line, Point, Rect, Size};
14090
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
     5
use land2d::Land2D;
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
     6
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
     7
use outline_template::OutlineTemplate;
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
     8
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
     9
pub struct OutlinePoints {
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    10
    pub islands: Vec<Vec<Point>>,
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    11
    pub fill_points: Vec<Point>,
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    12
    pub size: Size,
14099
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
    13
    pub play_box: Rect,
14090
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    14
}
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    15
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    16
impl OutlinePoints {
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    17
    pub fn from_outline_template<I: Iterator<Item = u32>>(
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    18
        outline_template: &OutlineTemplate,
14099
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
    19
        play_box: Rect,
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
    20
        size: Size,
14090
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    21
        random_numbers: &mut I,
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    22
    ) -> Self {
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    23
        Self {
14099
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
    24
            play_box,
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
    25
            size,
14090
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    26
            islands: outline_template
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    27
                .islands
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    28
                .iter()
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    29
                .map(|i| {
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    30
                    i.iter()
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    31
                        .zip(random_numbers.tuples())
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    32
                        .map(|(rect, (rnd_a, rnd_b))| {
14099
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
    33
                            rect.top_left()
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
    34
                                + Point::new(
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
    35
                                    (rnd_a % rect.width) as i32,
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
    36
                                    (rnd_b % rect.height) as i32,
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
    37
                                )
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
    38
                                + play_box.top_left()
14090
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    39
                        }).collect()
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    40
                }).collect(),
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    41
            fill_points: outline_template.fill_points.clone(),
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    42
        }
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    43
    }
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    44
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    45
    pub fn total_len(&self) -> usize {
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    46
        self.islands.iter().map(|i| i.len()).sum::<usize>() + self.fill_points.len()
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    47
    }
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    48
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    49
    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Point> {
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    50
        self.islands
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    51
            .iter_mut()
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    52
            .flat_map(|i| i.iter_mut())
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    53
            .chain(self.fill_points.iter_mut())
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    54
    }
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    55
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    56
    fn divide_edge<I: Iterator<Item = u32>>(
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    57
        &self,
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
    58
        segment: Line,
14090
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    59
        random_numbers: &mut I,
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
    60
    ) -> Option<Point> {
14102
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    61
        let min_distance = 40;
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    62
        // new point should fall inside this box
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    63
        let map_box = self.play_box.with_margin(min_distance);
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    64
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    65
        let p = Point::new(
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    66
            segment.end.y - segment.start.y,
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    67
            segment.start.x - segment.start.y,
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    68
        );
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    69
        let mid_point = segment.center();
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    70
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    71
        if (p.integral_norm() < min_distance as u32 * 3) || !map_box.contains_inside(p) {
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    72
            return None;
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    73
        }
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    74
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    75
        let full_box = Rect::from_size(Point::zero(), self.size).with_margin(min_distance);
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    76
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    77
        let mut dist_left = (self.size.width + self.size.height) as u32;
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    78
        let mut dist_right = dist_left;
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    79
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    80
        // find distances to map borders
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    81
        if p.x != 0 {
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    82
            // check against left border
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    83
            let iyl = (map_box.left() - mid_point.x) * p.y / p.x + mid_point.y;
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    84
            let dl = Point::new(mid_point.x - map_box.left(), mid_point.y - iyl).integral_norm();
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    85
            let t = p.x * (mid_point.x - full_box.left()) + p.y * (mid_point.y - iyl);
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    86
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    87
            if t > 0 {
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    88
                dist_left = dl;
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    89
            } else {
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    90
                dist_right = dl;
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    91
            }
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    92
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    93
            // right border
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    94
            let iyr = (map_box.right() - mid_point.x) * p.y / p.x + mid_point.y;
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    95
            let dr = Point::new(mid_point.x - full_box.right(), mid_point.y - iyr).integral_norm();
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    96
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    97
            if t > 0 {
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    98
                dist_right = dr;
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
    99
            } else {
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   100
                dist_left = dr;
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   101
            }
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   102
        }
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   103
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   104
        if p.y != 0 {
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   105
            // top border
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   106
            let ixl = (map_box.top() - mid_point.y) * p.x / p.y + mid_point.x;
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   107
            let dl = Point::new(mid_point.y - map_box.top(), mid_point.x - ixl).integral_norm();
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   108
            let t = p.y * (mid_point.y - full_box.top()) + p.x * (mid_point.x - ixl);
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   109
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   110
            if t > 0 {
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   111
                dist_left = min(dist_left, dl);
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   112
            } else {
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   113
                dist_right = min(dist_right, dl);
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   114
            }
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   115
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   116
            // bottom border
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   117
            let ixr = (map_box.bottom() - mid_point.y) * p.x / p.y + mid_point.x;
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   118
            let dr = Point::new(mid_point.y - full_box.bottom(), mid_point.x - ixr).integral_norm();
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   119
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   120
            if t > 0 {
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   121
                dist_right = min(dist_right, dr);
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   122
            } else {
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   123
                dist_left = min(dist_left, dr);
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   124
            }
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   125
        }
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   126
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   127
        // now go through all other segments
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 14099
diff changeset
   128
14090
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   129
        None
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   130
    }
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   131
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   132
    fn divide_edges<I: Iterator<Item = u32>>(&mut self, random_numbers: &mut I) {
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   133
        for is in 0..self.islands.len() {
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   134
            let mut i = 0;
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   135
            let mut segment;
14090
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   136
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   137
            loop {
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   138
                {
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   139
                    let island = &self.islands[is];
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   140
                    let mut end_point;
14090
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   141
                    if i < island.len() {
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   142
                        end_point = if i + 1 < island.len() {
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   143
                            island[i + 1]
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   144
                        } else {
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   145
                            island[0]
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   146
                        };
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   147
                    } else {
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   148
                        break;
14090
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   149
                    }
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   150
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   151
                    segment = Line::new(island[i], end_point);
14090
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   152
                }
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   153
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   154
                if let Some(new_point) = self.divide_edge(segment, random_numbers) {
14090
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   155
                    self.islands[is].insert(i + 1, new_point);
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   156
                    i += 2;
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   157
                } else {
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   158
                    i += 1;
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   159
                }
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   160
            }
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   161
        }
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   162
    }
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   163
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   164
    pub fn bezierize(&mut self) {
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   165
        unimplemented!()
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   166
    }
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   167
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   168
    pub fn distort<I: Iterator<Item = u32>>(&mut self, random_numbers: &mut I) {
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   169
        loop {
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   170
            let old_len = self.total_len();
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   171
            self.divide_edges(random_numbers);
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   172
14114
dbaa125a0fe9 fix infinite loop in landgen
alfadur
parents: 14102
diff changeset
   173
            if self.total_len() == old_len {
14090
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   174
                break;
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   175
            }
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   176
        }
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   177
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   178
        self.bezierize();
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   179
    }
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   180
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   181
    pub fn draw<T: Copy + PartialEq>(&self, land: &mut Land2D<T>, value: T) {
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   182
        for segment in self.segments_iter() {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   183
            land.draw_line(segment, value);
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   184
        }
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   185
    }
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   186
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   187
    fn segments_iter(&self) -> OutlineSegmentsIterator {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   188
        OutlineSegmentsIterator {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   189
            outline: self,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   190
            island: 0,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   191
            index: 0,
14090
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   192
        }
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   193
    }
abb42ba345b6 Rework lib structure, no code changes
unC0Rr
parents:
diff changeset
   194
}
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   195
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   196
struct OutlineSegmentsIterator<'a> {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   197
    outline: &'a OutlinePoints,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   198
    island: usize,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   199
    index: usize,
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   200
}
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   201
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   202
impl<'a> Iterator for OutlineSegmentsIterator<'a> {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   203
    type Item = Line;
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   204
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   205
    fn next(&mut self) -> Option<Self::Item> {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   206
        if self.island < self.outline.islands.len() {
14099
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   207
            if self.index + 1 < self.outline.islands[self.island].len() {
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   208
                let result = Some(Line::new(
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   209
                    self.outline.islands[self.island][self.index],
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   210
                    self.outline.islands[self.island][self.index + 1],
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   211
                ));
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   212
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   213
                self.index += 1;
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   214
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   215
                result
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   216
            } else if self.index + 1 == self.outline.islands[self.island].len() {
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   217
                let result = Some(Line::new(
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   218
                    self.outline.islands[self.island][self.index],
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   219
                    self.outline.islands[self.island][0],
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   220
                ));
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   221
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   222
                self.island += 1;
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   223
                self.index = 0;
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   224
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   225
                result
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   226
            } else {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   227
                self.island += 1;
14099
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   228
                self.index = 0;
14097
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   229
                self.next()
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   230
            }
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   231
        } else {
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   232
            None
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   233
        }
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   234
    }
e5904ead4864 Introduce OutlineSegmentsIterator, some refactoring
unC0Rr
parents: 14090
diff changeset
   235
}
14099
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   236
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   237
#[test()]
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   238
fn points_test() {
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   239
    let mut points = OutlinePoints {
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   240
        islands: vec![
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   241
            vec![Point::new(0, 0), Point::new(20, 0), Point::new(30, 30)],
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   242
            vec![Point::new(10, 15), Point::new(15, 20), Point::new(20, 15)],
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   243
        ],
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   244
        fill_points: vec![Point::new(1, 1)],
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   245
        play_box: Rect::from_box(0, 100, 0, 100).with_margin(10),
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   246
        size: Size::square(100),
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   247
    };
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   248
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   249
    let segments: Vec<Line> = points.segments_iter().collect();
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   250
    assert_eq!(
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   251
        segments.first(),
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   252
        Some(&Line::new(Point::new(0, 0), Point::new(20, 0)))
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   253
    );
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   254
    assert_eq!(
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   255
        segments.last(),
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   256
        Some(&Line::new(Point::new(20, 15), Point::new(10, 15)))
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   257
    );
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   258
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   259
    points.iter_mut().for_each(|p| p.x = 2);
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   260
    assert_eq!(points.fill_points[0].x, 2);
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   261
    assert_eq!(points.islands[0][0].x, 2);
bf40b5f938b0 - Add methods to work with Rect as box
unC0Rr
parents: 14098
diff changeset
   262
}