rust/landgen/src/outline.rs
changeset 15850 44b49f255e31
parent 15777 2eb3469a28a0
child 15942 6e22f4390b7e
equal deleted inserted replaced
15849:64b0a5cead86 15850:44b49f255e31
     1 use itertools::Itertools;
     1 use itertools::Itertools;
     2 use std::cmp::min;
     2 use std::cmp::min;
     3 
     3 
     4 use integral_geometry::{Line, Ray, Point, Polygon, Rect, Size};
     4 use integral_geometry::{Line, Point, Polygon, Ray, Rect, Size};
     5 use land2d::Land2D;
     5 use land2d::Land2D;
     6 
     6 
     7 use crate::outline_template::OutlineTemplate;
     7 use crate::outline_template::OutlineTemplate;
     8 
     8 
     9 pub struct OutlinePoints {
     9 pub struct OutlinePoints {
    74 
    74 
    75         #[inline]
    75         #[inline]
    76         fn solve_intersection(
    76         fn solve_intersection(
    77             intersections_box: &Rect,
    77             intersections_box: &Rect,
    78             ray: &Ray,
    78             ray: &Ray,
    79             edge: &Line
    79             edge: &Line,
    80         ) -> Option<(i32, u32)>
    80         ) -> Option<(i32, u32)> {
    81         {
       
    82             let edge_dir = edge.scaled_direction();
    81             let edge_dir = edge.scaled_direction();
    83             let aqpb = ray.direction.cross(edge_dir) as i64;
    82             let aqpb = ray.direction.cross(edge_dir) as i64;
    84 
    83 
    85             if aqpb != 0 {
    84             if aqpb != 0 {
    86                 let mut iy =
    85                 let mut iy = ((((edge.start.x - ray.start.x) as i64 * ray.direction.y as i64
    87                     ((((edge.start.x - ray.start.x) as i64 * ray.direction.y as i64
    86                     + ray.start.y as i64 * ray.direction.x as i64)
    88                         + ray.start.y as i64 * ray.direction.x as i64)
       
    89                     * edge_dir.y as i64
    87                     * edge_dir.y as i64
    90                     - edge.start.y as i64 * edge_dir.x as i64 * ray.direction.y as i64)
    88                     - edge.start.y as i64 * edge_dir.x as i64 * ray.direction.y as i64)
    91                     / aqpb) as i32;
    89                     / aqpb) as i32;
    92 
    90 
    93                 // is there better way to do it?
    91                 // is there better way to do it?
   145             dist_left = (mid_point - left_intersection).integral_norm();
   143             dist_left = (mid_point - left_intersection).integral_norm();
   146 
   144 
   147             // same for the right border
   145             // same for the right border
   148             let right_intersection = Point::new(
   146             let right_intersection = Point::new(
   149                 map_box.right(),
   147                 map_box.right(),
   150                 mid_point.y + normal.tangent_mul(map_box.right() - mid_point.x)  ,
   148                 mid_point.y + normal.tangent_mul(map_box.right() - mid_point.x),
   151             );
   149             );
   152             dist_right = (mid_point - right_intersection).integral_norm();
   150             dist_right = (mid_point - right_intersection).integral_norm();
   153 
   151 
   154             if normal.x > 0 {
   152             if normal.x > 0 {
   155                 std::mem::swap(&mut dist_left, &mut dist_right);
   153                 std::mem::swap(&mut dist_left, &mut dist_right);
   201         for pi in self.iter().cloned() {
   199         for pi in self.iter().cloned() {
   202             if pi != segment.start && pi != segment.end {
   200             if pi != segment.start && pi != segment.end {
   203                 if intersects(&pi.ray_with_dir(normal), &segment) {
   201                 if intersects(&pi.ray_with_dir(normal), &segment) {
   204                     // ray from segment.start
   202                     // ray from segment.start
   205                     if let Some((t, d)) = solve_intersection(
   203                     if let Some((t, d)) = solve_intersection(
   206                         &self.intersections_box, &normal_ray, &segment.start.line_to(pi),
   204                         &self.intersections_box,
       
   205                         &normal_ray,
       
   206                         &segment.start.line_to(pi),
   207                     ) {
   207                     ) {
   208                         if t > 0 {
   208                         if t > 0 {
   209                             dist_right = min(dist_right, d);
   209                             dist_right = min(dist_right, d);
   210                         } else {
   210                         } else {
   211                             dist_left = min(dist_left, d);
   211                             dist_left = min(dist_left, d);
   212                         }
   212                         }
   213                     }
   213                     }
   214 
   214 
   215                     // ray from segment.end
   215                     // ray from segment.end
   216                     if let Some((t, d)) = solve_intersection(
   216                     if let Some((t, d)) = solve_intersection(
   217                         &self.intersections_box, &normal_ray, &segment.end.line_to(pi)
   217                         &self.intersections_box,
       
   218                         &normal_ray,
       
   219                         &segment.end.line_to(pi),
   218                     ) {
   220                     ) {
   219                         if t > 0 {
   221                         if t > 0 {
   220                             dist_right = min(dist_right, d);
   222                             dist_right = min(dist_right, d);
   221                         } else {
   223                         } else {
   222                             dist_left = min(dist_left, d);
   224                             dist_left = min(dist_left, d);