rust/landgen/src/outline.rs
changeset 14078 bf40b5f938b0
parent 14077 5ade484f3351
child 14081 5d42204ac35e
equal deleted inserted replaced
14077:5ade484f3351 14078:bf40b5f938b0
     1 use itertools::Itertools;
     1 use itertools::Itertools;
     2 
     2 
     3 use integral_geometry::{Line, Point, Size};
     3 use integral_geometry::{Line, Point, Rect, Size};
     4 use land2d::Land2D;
     4 use land2d::Land2D;
     5 
     5 
     6 use outline_template::OutlineTemplate;
     6 use outline_template::OutlineTemplate;
     7 
     7 
     8 pub struct OutlinePoints {
     8 pub struct OutlinePoints {
     9     pub islands: Vec<Vec<Point>>,
     9     pub islands: Vec<Vec<Point>>,
    10     pub fill_points: Vec<Point>,
    10     pub fill_points: Vec<Point>,
    11     pub size: Size,
    11     pub size: Size,
       
    12     pub play_box: Rect,
    12 }
    13 }
    13 
    14 
    14 impl OutlinePoints {
    15 impl OutlinePoints {
    15     pub fn from_outline_template<I: Iterator<Item = u32>>(
    16     pub fn from_outline_template<I: Iterator<Item = u32>>(
    16         outline_template: &OutlineTemplate,
    17         outline_template: &OutlineTemplate,
       
    18         play_box: Rect,
       
    19         size: Size,
    17         random_numbers: &mut I,
    20         random_numbers: &mut I,
    18     ) -> Self {
    21     ) -> Self {
    19         Self {
    22         Self {
       
    23             play_box,
       
    24             size,
    20             islands: outline_template
    25             islands: outline_template
    21                 .islands
    26                 .islands
    22                 .iter()
    27                 .iter()
    23                 .map(|i| {
    28                 .map(|i| {
    24                     i.iter()
    29                     i.iter()
    25                         .zip(random_numbers.tuples())
    30                         .zip(random_numbers.tuples())
    26                         .map(|(rect, (rnd_a, rnd_b))| {
    31                         .map(|(rect, (rnd_a, rnd_b))| {
    27                             Point::new(
    32                             rect.top_left()
    28                                 rect.x + (rnd_a % rect.width) as i32,
    33                                 + Point::new(
    29                                 rect.y + (rnd_b % rect.height) as i32,
    34                                     (rnd_a % rect.width) as i32,
    30                             )
    35                                     (rnd_b % rect.height) as i32,
       
    36                                 )
       
    37                                 + play_box.top_left()
    31                         }).collect()
    38                         }).collect()
    32                 }).collect(),
    39                 }).collect(),
    33             fill_points: outline_template.fill_points.clone(),
    40             fill_points: outline_template.fill_points.clone(),
    34             size: outline_template.size,
       
    35         }
    41         }
    36     }
    42     }
    37 
    43 
    38     pub fn total_len(&self) -> usize {
    44     pub fn total_len(&self) -> usize {
    39         self.islands.iter().map(|i| i.len()).sum::<usize>() + self.fill_points.len()
    45         self.islands.iter().map(|i| i.len()).sum::<usize>() + self.fill_points.len()
    49     fn divide_edge<I: Iterator<Item = u32>>(
    55     fn divide_edge<I: Iterator<Item = u32>>(
    50         &self,
    56         &self,
    51         segment: Line,
    57         segment: Line,
    52         random_numbers: &mut I,
    58         random_numbers: &mut I,
    53     ) -> Option<Point> {
    59     ) -> Option<Point> {
    54 
       
    55         None
    60         None
    56     }
    61     }
    57 
    62 
    58     fn divide_edges<I: Iterator<Item = u32>>(&mut self, random_numbers: &mut I) {
    63     fn divide_edges<I: Iterator<Item = u32>>(&mut self, random_numbers: &mut I) {
    59         for is in 0..self.islands.len() {
    64         for is in 0..self.islands.len() {
   128 impl<'a> Iterator for OutlineSegmentsIterator<'a> {
   133 impl<'a> Iterator for OutlineSegmentsIterator<'a> {
   129     type Item = Line;
   134     type Item = Line;
   130 
   135 
   131     fn next(&mut self) -> Option<Self::Item> {
   136     fn next(&mut self) -> Option<Self::Item> {
   132         if self.island < self.outline.islands.len() {
   137         if self.island < self.outline.islands.len() {
   133             if self.index + 1 < self.outline.islands[self.index].len() {
   138             if self.index + 1 < self.outline.islands[self.island].len() {
   134                 Some(Line::new(
   139                 let result = Some(Line::new(
   135                     self.outline.islands[self.index][self.index],
   140                     self.outline.islands[self.island][self.index],
   136                     self.outline.islands[self.index][self.index + 1],
   141                     self.outline.islands[self.island][self.index + 1],
   137                 ))
   142                 ));
   138             } else if self.index + 1 == self.outline.islands[self.index].len() {
   143 
   139                 Some(Line::new(
   144                 self.index += 1;
   140                     self.outline.islands[self.index][self.index],
   145 
   141                     self.outline.islands[self.index][0],
   146                 result
   142                 ))
   147             } else if self.index + 1 == self.outline.islands[self.island].len() {
       
   148                 let result = Some(Line::new(
       
   149                     self.outline.islands[self.island][self.index],
       
   150                     self.outline.islands[self.island][0],
       
   151                 ));
       
   152 
       
   153                 self.island += 1;
       
   154                 self.index = 0;
       
   155 
       
   156                 result
   143             } else {
   157             } else {
   144                 self.island += 1;
   158                 self.island += 1;
       
   159                 self.index = 0;
   145                 self.next()
   160                 self.next()
   146             }
   161             }
   147         } else {
   162         } else {
   148             None
   163             None
   149         }
   164         }
   150     }
   165     }
   151 }
   166 }
       
   167 
       
   168 #[test()]
       
   169 fn points_test() {
       
   170     let mut points = OutlinePoints {
       
   171         islands: vec![
       
   172             vec![Point::new(0, 0), Point::new(20, 0), Point::new(30, 30)],
       
   173             vec![Point::new(10, 15), Point::new(15, 20), Point::new(20, 15)],
       
   174         ],
       
   175         fill_points: vec![Point::new(1, 1)],
       
   176         play_box: Rect::from_box(0, 100, 0, 100).with_margin(10),
       
   177         size: Size::square(100),
       
   178     };
       
   179 
       
   180     let segments: Vec<Line> = points.segments_iter().collect();
       
   181     assert_eq!(
       
   182         segments.first(),
       
   183         Some(&Line::new(Point::new(0, 0), Point::new(20, 0)))
       
   184     );
       
   185     assert_eq!(
       
   186         segments.last(),
       
   187         Some(&Line::new(Point::new(20, 15), Point::new(10, 15)))
       
   188     );
       
   189 
       
   190     points.iter_mut().for_each(|p| p.x = 2);
       
   191     assert_eq!(points.fill_points[0].x, 2);
       
   192     assert_eq!(points.islands[0][0].x, 2);
       
   193 }