From a2e2c3311eb7a0ca7cc24e49636a3dc4c0a622aa Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Tue, 12 Feb 2019 13:42:52 -0800 Subject: [PATCH] drawing border arrows way better --- data/polygons/montlake.poly | 4 +- editor/src/render/intersection.rs | 86 +++++++++++++++++++++---------- ezgui/src/color.rs | 1 + geom/src/line.rs | 14 ----- 4 files changed, 62 insertions(+), 43 deletions(-) diff --git a/data/polygons/montlake.poly b/data/polygons/montlake.poly index 44254a8d4a..780aa980c8 100644 --- a/data/polygons/montlake.poly +++ b/data/polygons/montlake.poly @@ -2,8 +2,8 @@ montlake 1 -122.3218 47.6475 -122.2985 47.6475 - -122.2985 47.6323 - -122.3218 47.6323 + -122.2985 47.6315 + -122.3218 47.6315 -122.3218 47.6475 END END diff --git a/editor/src/render/intersection.rs b/editor/src/render/intersection.rs index 30b6c77db0..65fcca4367 100644 --- a/editor/src/render/intersection.rs +++ b/editor/src/render/intersection.rs @@ -4,7 +4,7 @@ use crate::render::{DrawCrosswalk, DrawTurn, RenderOptions, Renderable, MIN_ZOOM use ezgui::{Color, Drawable, GfxCtx, Prerender, ScreenPt, Text}; use geom::{Bounds, Circle, Distance, Duration, Line, Polygon, Pt2D}; use map_model::{ - Cycle, Intersection, IntersectionID, IntersectionType, Map, TurnPriority, TurnType, + Cycle, Intersection, IntersectionID, IntersectionType, Map, Road, TurnPriority, TurnType, LANE_THICKNESS, }; use ordered_float::NotNan; @@ -47,33 +47,15 @@ impl DrawIntersection { .map(|p| (cs.get("sidewalk"), p)), ); if i.intersection_type == IntersectionType::Border { - let r = map.get_r(*i.roads.iter().next().unwrap()); - let angle = if i.incoming_lanes.is_empty() { - r.center_pts.first_line().angle() - } else { - r.center_pts.last_line().angle() - }; - let center = i.polygon.center(); - // TODO < the DEGENERATE_INTERSECTION_HALF_LENGTH but still kinda related - let line = Line::new( - center.project_away(Distance::meters(4.0), angle.opposite()), - center.project_away(Distance::meters(4.0), angle), - ); - default_geom.extend( - line.make_arrow((r.all_lanes().len() as f64) * LANE_THICKNESS / 3.0) - .into_iter() - .map(|p| (cs.get_def("border node arrow", Color::PURPLE), p)), - ); - - // TODO Do this better. - if !i.incoming_lanes.is_empty() && i.outgoing_lanes.is_empty() { - default_geom.extend( - line.reverse() - .make_arrow((r.all_lanes().len() as f64) * LANE_THICKNESS / 3.0) - .into_iter() - .map(|p| (cs.get("border node arrow"), p)), - ); + if i.roads.len() != 1 { + panic!("Border {} has {} roads!", i.id, i.roads.len()); } + let r = map.get_r(*i.roads.iter().next().unwrap()); + default_geom.extend( + calculate_border_arrows(i, r) + .into_iter() + .map(|p| (cs.get_def("incoming border node arrow", Color::PURPLE), p)), + ); } DrawIntersection { @@ -433,3 +415,53 @@ fn find_pts_between(pts: &Vec, start: Pt2D, end: Pt2D) -> Option // Didn't find end None } + +fn calculate_border_arrows(i: &Intersection, r: &Road) -> Vec { + let mut result = Vec::new(); + + // These arrows should point from the void to the road + if !i.outgoing_lanes.is_empty() { + // The line starts at the border and points down the road + let (line, width) = if r.dst_i == i.id { + let width = (r.children_forwards.len() as f64) * LANE_THICKNESS; + ( + r.center_pts.last_line().shift_left(width / 2.0).reverse(), + width, + ) + } else { + let width = (r.children_forwards.len() as f64) * LANE_THICKNESS; + (r.center_pts.first_line().shift_right(width / 2.0), width) + }; + result.extend( + // DEGENERATE_INTERSECTION_HALF_LENGTH is 5m... + Line::new( + line.unbounded_dist_along(Distance::meters(-9.5)), + line.unbounded_dist_along(Distance::meters(-0.5)), + ) + .make_arrow(width / 3.0), + ); + } + + // These arrows should point from the road to the void + if !i.incoming_lanes.is_empty() { + // The line starts at the border and points down the road + let (line, width) = if r.dst_i == i.id { + let width = (r.children_forwards.len() as f64) * LANE_THICKNESS; + ( + r.center_pts.last_line().shift_right(width / 2.0).reverse(), + width, + ) + } else { + let width = (r.children_backwards.len() as f64) * LANE_THICKNESS; + (r.center_pts.first_line().shift_left(width / 2.0), width) + }; + result.extend( + Line::new( + line.unbounded_dist_along(Distance::meters(-0.5)), + line.unbounded_dist_along(Distance::meters(-9.5)), + ) + .make_arrow(width / 3.0), + ); + } + result +} diff --git a/ezgui/src/color.rs b/ezgui/src/color.rs index 3f93a21094..9045a7b58a 100644 --- a/ezgui/src/color.rs +++ b/ezgui/src/color.rs @@ -26,6 +26,7 @@ impl Color { pub const YELLOW: Color = Color::rgb_f(1.0, 1.0, 0.0); pub const PURPLE: Color = Color::rgb_f(0.5, 0.0, 0.5); pub const PINK: Color = Color::rgb_f(1.0, 0.41, 0.71); + pub const ORANGE: Color = Color::rgb_f(1.0, 0.55, 0.0); // TODO should assert stuff about the inputs diff --git a/geom/src/line.rs b/geom/src/line.rs index b17fc633a3..5196a31b7e 100644 --- a/geom/src/line.rs +++ b/geom/src/line.rs @@ -167,13 +167,6 @@ impl Line { self.pt1().x() + percent * (self.pt2().x() - self.pt1().x()), self.pt1().y() + percent * (self.pt2().y() - self.pt1().y()), ) - // TODO unit test - /* - let res_len = euclid_dist((pt1, &Pt2D::new(res[0], res[1]))); - if res_len != dist_along { - println!("whats the delta btwn {} and {}?", res_len, dist_along); - } - */ } pub fn unbounded_dist_along(&self, dist: Distance) -> Pt2D { @@ -183,13 +176,6 @@ impl Line { self.pt1().x() + percent * (self.pt2().x() - self.pt1().x()), self.pt1().y() + percent * (self.pt2().y() - self.pt1().y()), ) - // TODO unit test - /* - let res_len = euclid_dist((pt1, &Pt2D::new(res[0], res[1]))); - if res_len != dist_along { - println!("whats the delta btwn {} and {}?", res_len, dist_along); - } - */ } pub fn contains_pt(&self, pt: Pt2D) -> bool {