From be9671a51f2cfb883345573f84da13142c8d9750 Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Mon, 16 Mar 2020 18:27:33 -0700 Subject: [PATCH] more fixes for left-hand maps (#27): - avoid a crash by deduping intersection polygon points - make shared sidewalk corners saner by flipping order of points - improve crosswalk determination --- game/src/render/intersection.rs | 7 ++++- geom/src/pt.rs | 1 + map_model/src/make/initial/geometry.rs | 1 + map_model/src/make/turns.rs | 38 +++++++++++++++----------- map_model/src/map.rs | 4 +++ 5 files changed, 34 insertions(+), 17 deletions(-) diff --git a/game/src/render/intersection.rs b/game/src/render/intersection.rs index 96f6a44b24..c191937ec9 100644 --- a/game/src/render/intersection.rs +++ b/game/src/render/intersection.rs @@ -6,6 +6,7 @@ use crate::render::{ use abstutil::Timer; use ezgui::{Color, Drawable, GeomBatch, GfxCtx, Line, Prerender, Text}; use geom::{Angle, Distance, Line, PolyLine, Polygon, Pt2D, Time, EPSILON_DIST}; +use map_model::raw::DrivingSide; use map_model::{ Intersection, IntersectionID, IntersectionType, Map, Road, RoadWithStopSign, Turn, TurnType, }; @@ -205,8 +206,12 @@ pub fn calculate_corners(i: &Intersection, map: &Map, timer: &mut Timer) -> Vec< // Intersection polygons are constructed in clockwise order, so do corner2 to corner1. // TODO This threshold is higher than the 0.1 intersection polygons use to dedupe // because of jagged lane teeth from bad polyline shifting. Seemingly. + let mut i_pts = i.polygon.points().clone(); + if map.get_driving_side() == DrivingSide::Left { + i_pts.reverse(); + } if let Some(mut pts_between) = - Pt2D::find_pts_between(&i.polygon.points(), corner2, corner1, Distance::meters(0.5)) + Pt2D::find_pts_between(&i_pts, corner2, corner1, Distance::meters(0.5)) { pts_between.push(src_line.pt2()); // If the intersection of the two lines isn't actually inside, then just exclude diff --git a/geom/src/pt.rs b/geom/src/pt.rs index ea18caf369..d000b21d77 100644 --- a/geom/src/pt.rs +++ b/geom/src/pt.rs @@ -149,6 +149,7 @@ impl Pt2D { result } + // TODO Try to deprecate in favor of Ring::get_shorter_slice_btwn pub fn find_pts_between( pts: &Vec, start: Pt2D, diff --git a/map_model/src/make/initial/geometry.rs b/map_model/src/make/initial/geometry.rs index 750f087411..36aa1865e3 100644 --- a/map_model/src/make/initial/geometry.rs +++ b/map_model/src/make/initial/geometry.rs @@ -327,6 +327,7 @@ fn generalized_trim_back( deduped = Pt2D::approx_dedupe(deduped, Distance::meters(0.1)); let center = Pt2D::center(&deduped); deduped.sort_by_key(|pt| pt.angle_to(center).normalized_degrees() as i64); + deduped = Pt2D::approx_dedupe(deduped, Distance::meters(0.1)); deduped = close_off_polygon(deduped); if main_result.len() == deduped.len() { (main_result, debug) diff --git a/map_model/src/make/turns.rs b/map_model/src/make/turns.rs index 60271f1cd8..dc248da9b3 100644 --- a/map_model/src/make/turns.rs +++ b/map_model/src/make/turns.rs @@ -304,6 +304,14 @@ fn make_walking_turns( .collect(); let mut result: Vec = Vec::new(); + // I'm a bit confused when to do -1 and +1 honestly, but this works in practice. Angle sorting + // may be a little backwards. + let idx_offset = if driving_side == DrivingSide::Right { + -1 + } else { + 1 + }; + if roads.len() == 2 { if let Some(turns) = make_degenerate_crosswalks(i.id, lanes, roads[0], roads[1]) { result.extend(turns); @@ -313,7 +321,8 @@ fn make_walking_turns( if let Some(l1) = get_sidewalk(lanes, roads[idx1].incoming_lanes(i.id)) { if let Some(l2) = get_sidewalk( lanes, - abstutil::wraparound_get(&roads, (idx1 as isize) - 1).outgoing_lanes(i.id), + abstutil::wraparound_get(&roads, (idx1 as isize) + idx_offset) + .outgoing_lanes(i.id), ) { if l1.last_pt() != l2.first_pt() { let geom = make_shared_sidewalk_corner(driving_side, i, l1, l2, timer); @@ -360,14 +369,6 @@ fn make_walking_turns( return result; } - // I'm a bit confused when to do -1 and +1 honestly, but this works in practice. Angle sorting - // may be a little backwards. - let idx_offset = if driving_side == DrivingSide::Right { - -1 - } else { - 1 - }; - for idx1 in 0..roads.len() { if let Some(l1) = get_sidewalk(lanes, roads[idx1].incoming_lanes(i.id)) { // Make the crosswalk to the other side @@ -399,7 +400,7 @@ fn make_walking_turns( } } else if let Some(l2) = get_sidewalk( lanes, - abstutil::wraparound_get(&roads, (idx1 as isize) - 1).incoming_lanes(i.id), + abstutil::wraparound_get(&roads, (idx1 as isize) + idx_offset).incoming_lanes(i.id), ) { // Adjacent road is missing a sidewalk on the near side, but has one on the far // side @@ -410,18 +411,21 @@ fn make_walking_turns( // TODO Refactor and loop until we find something to connect it to? if let Some(l2) = get_sidewalk( lanes, - abstutil::wraparound_get(&roads, (idx1 as isize) - 2).outgoing_lanes(i.id), + abstutil::wraparound_get(&roads, (idx1 as isize) + 2 * idx_offset) + .outgoing_lanes(i.id), ) { result.extend(make_crosswalks(i.id, l1, l2)); } else if let Some(l2) = get_sidewalk( lanes, - abstutil::wraparound_get(&roads, (idx1 as isize) - 2).incoming_lanes(i.id), + abstutil::wraparound_get(&roads, (idx1 as isize) + 2 * idx_offset) + .incoming_lanes(i.id), ) { result.extend(make_crosswalks(i.id, l1, l2)); } else if roads.len() > 3 { if let Some(l2) = get_sidewalk( lanes, - abstutil::wraparound_get(&roads, (idx1 as isize) - 3).outgoing_lanes(i.id), + abstutil::wraparound_get(&roads, (idx1 as isize) + 3 * idx_offset) + .outgoing_lanes(i.id), ) { result.extend(make_crosswalks(i.id, l1, l2)); } @@ -560,9 +564,11 @@ fn make_shared_sidewalk_corner( // to corner1 below. let mut pts_between = vec![l2.first_pt()]; // Intersection polygons are constructed in clockwise order, so do corner2 to corner1. - if let Some(pts) = - Pt2D::find_pts_between(&i.polygon.points(), corner2, corner1, Distance::meters(0.5)) - { + let mut i_pts = i.polygon.points().clone(); + if driving_side == DrivingSide::Left { + i_pts.reverse(); + } + if let Some(pts) = Pt2D::find_pts_between(&i_pts, corner2, corner1, Distance::meters(0.5)) { let mut deduped = pts.clone(); deduped.dedup(); if deduped.len() >= 2 { diff --git a/map_model/src/map.rs b/map_model/src/map.rs index de9be5a8b5..58c41cb705 100644 --- a/map_model/src/map.rs +++ b/map_model/src/map.rs @@ -672,6 +672,10 @@ impl Map { pub fn left_shift_line(&self, line: Line, width: Distance) -> Line { self.driving_side.left_shift_line(line, width) } + // Last resort + pub fn get_driving_side(&self) -> DrivingSide { + self.driving_side + } } impl Map {