rust/landgen/src/outline.rs
changeset 14110 21642eb0ff29
parent 14109 913be386b413
child 14111 269f13ac670d
equal deleted inserted replaced
14109:913be386b413 14110:21642eb0ff29
   110 
   110 
   111         if (p.integral_norm() < min_distance as u32 * 3) || !map_box.contains_inside(mid_point) {
   111         if (p.integral_norm() < min_distance as u32 * 3) || !map_box.contains_inside(mid_point) {
   112             return None;
   112             return None;
   113         }
   113         }
   114 
   114 
   115         let full_box = Rect::at_origin(self.size).with_margin(min_distance);
       
   116 
       
   117         let mut dist_left = (self.size.width + self.size.height) as u32;
   115         let mut dist_left = (self.size.width + self.size.height) as u32;
   118         let mut dist_right = dist_left;
   116         let mut dist_right = dist_left;
   119 
   117 
   120         // find distances to map borders
   118         // find distances to map borders
   121         if p.x != 0 {
   119         if p.x != 0 {
   122             // check against left border
   120             // where the normal line intersects the left map border
   123             let iyl = (map_box.left() - mid_point.x) * p.y / p.x + mid_point.y;
   121             let left_intersection = Point::new(
   124             let dl = Point::new(mid_point.x - map_box.left(), mid_point.y - iyl).integral_norm();
   122                 map_box.left(),
   125             let t = p.dot(mid_point - Point::new(full_box.left(), iyl));
   123                 (map_box.left() - mid_point.x) * p.y / p.x + mid_point.y);
   126 
   124             dist_left = (mid_point - left_intersection).integral_norm();
   127             if t > 0 {
   125 
   128                 dist_left = dl;
   126             // same for the right border
   129             } else {
   127             let right_intersection = Point::new(
   130                 dist_right = dl;
   128                 map_box.right(),
   131             }
   129                 (map_box.right() - mid_point.x) * p.y / p.x + mid_point.y);
   132 
   130             dist_right = (mid_point - right_intersection).integral_norm();
   133             // right border
   131 
   134             let iyr = (map_box.right() - mid_point.x) * p.y / p.x + mid_point.y;
   132             if p.dot(mid_point - left_intersection) < 0 {
   135             let dr = Point::new(mid_point.x - full_box.right(), mid_point.y - iyr).integral_norm();
   133                 std::mem::swap(&mut dist_left, &mut dist_right);
   136 
       
   137             if t > 0 {
       
   138                 dist_right = dr;
       
   139             } else {
       
   140                 dist_left = dr;
       
   141             }
   134             }
   142         }
   135         }
   143 
   136 
   144         if p.y != 0 {
   137         if p.y != 0 {
   145             // top border
   138             // where the normal line intersects the top map border
   146             let ixl = (map_box.top() - mid_point.y) * p.x / p.y + mid_point.x;
   139             let top_intersection = Point::new(
   147             let dl = Point::new(mid_point.y - map_box.top(), mid_point.x - ixl).integral_norm();
   140                 (map_box.top() - mid_point.y) * p.x / p.y + mid_point.x,
   148             let t = p.dot(mid_point - Point::new(ixl, full_box.top()));
   141                 map_box.top());
   149 
   142             let dl = (mid_point - top_intersection).integral_norm();
   150             if t > 0 {
   143 
       
   144             // same for the bottom border
       
   145             let bottom_intersection = Point::new(
       
   146                 (map_box.bottom() - mid_point.y) * p.x / p.y + mid_point.x,
       
   147                 map_box.bottom());
       
   148             let dr = (mid_point - bottom_intersection).integral_norm();
       
   149 
       
   150             if p.dot(mid_point - top_intersection) > 0 {
   151                 dist_left = min(dist_left, dl);
   151                 dist_left = min(dist_left, dl);
   152             } else {
       
   153                 dist_right = min(dist_right, dl);
       
   154             }
       
   155 
       
   156             // bottom border
       
   157             let ixr = (map_box.bottom() - mid_point.y) * p.x / p.y + mid_point.x;
       
   158             let dr = Point::new(mid_point.y - full_box.bottom(), mid_point.x - ixr).integral_norm();
       
   159 
       
   160             if t > 0 {
       
   161                 dist_right = min(dist_right, dr);
   152                 dist_right = min(dist_right, dr);
   162             } else {
   153             } else {
   163                 dist_left = min(dist_left, dr);
   154                 dist_left = min(dist_left, dr);
       
   155                 dist_right = min(dist_right, dl);
   164             }
   156             }
   165         }
   157         }
   166 
   158 
   167         // now go through all other segments
   159         // now go through all other segments
   168         for s in self.segments_iter() {
   160         for s in self.segments_iter() {