include more pts in the intersection polygon to only cover area from the original road bands. also fix a bug deduping points in the polygon.

This commit is contained in:
Dustin Carlino 2019-01-19 20:29:13 -08:00
parent e403a6388d
commit fad89ddffa
5 changed files with 34 additions and 20 deletions

View File

@ -4,9 +4,7 @@
- generalized_trim_back - generalized_trim_back
- breaks down when we have jagged lane endings due to polyline shift angle correction - breaks down when we have jagged lane endings due to polyline shift angle correction
- definitely wind up with some extra stuff in the polygon... including the final hit probably helps
- sometimes a lane polyline hits the perpendicular of a trimmed road! trim a bit further to handle that? - sometimes a lane polyline hits the perpendicular of a trimmed road! trim a bit further to handle that?
- some sidewalk corners are too eager now
- if some centers dont change enough, trim them back a little extra. ex: montlake bridge - if some centers dont change enough, trim them back a little extra. ex: montlake bridge
- handle small roads again somehow? - handle small roads again somehow?

View File

@ -2,6 +2,7 @@
## Quick n easy ## Quick n easy
- color roads as solid black when zoomed out, and make intersections similar (except for stop sign / signal)
- audit all panics - audit all panics
- tune text color, size, padding - tune text color, size, padding
- sort the top menus - sort the top menus

View File

@ -298,13 +298,13 @@ pub fn draw_signal_diagram(
fn find_pts_between(pts: &Vec<Pt2D>, start: Pt2D, end: Pt2D) -> Option<Vec<Pt2D>> { fn find_pts_between(pts: &Vec<Pt2D>, start: Pt2D, end: Pt2D) -> Option<Vec<Pt2D>> {
let mut result = Vec::new(); let mut result = Vec::new();
for pt in pts { for pt in pts {
if result.is_empty() && pt.approx_eq(start) { if result.is_empty() && pt.approx_eq(start, 1.0 * si::M) {
result.push(*pt); result.push(*pt);
} else if !result.is_empty() { } else if !result.is_empty() {
result.push(*pt); result.push(*pt);
} }
// start and end might be the same. // start and end might be the same.
if !result.is_empty() && pt.approx_eq(end) { if !result.is_empty() && pt.approx_eq(end, 1.0 * si::M) {
return Some(result); return Some(result);
} }
} }
@ -317,7 +317,7 @@ fn find_pts_between(pts: &Vec<Pt2D>, start: Pt2D, end: Pt2D) -> Option<Vec<Pt2D>
// Go through again, looking for end // Go through again, looking for end
for pt in pts { for pt in pts {
result.push(*pt); result.push(*pt);
if pt.approx_eq(end) { if pt.approx_eq(end, 1.0 * si::M) {
return Some(result); return Some(result);
} }
} }

View File

@ -32,9 +32,8 @@ impl Pt2D {
} }
// TODO This is a small first step... // TODO This is a small first step...
pub fn approx_eq(&self, other: Pt2D) -> bool { pub fn approx_eq(&self, other: Pt2D, threshold: si::Meter<f64>) -> bool {
let eps = 0.01; self.dist_to(other) <= threshold
(self.x - other.x).abs() < eps && (self.y - other.y) < eps
} }
pub fn from_gps(gps: LonLat, b: &GPSBounds) -> Option<Pt2D> { pub fn from_gps(gps: LonLat, b: &GPSBounds) -> Option<Pt2D> {

View File

@ -1,6 +1,7 @@
use crate::{Intersection, IntersectionID, Road, RoadID, LANE_THICKNESS}; use crate::{Intersection, IntersectionID, Road, RoadID, LANE_THICKNESS};
use abstutil::wraparound_get;
use dimensioned::si; use dimensioned::si;
use geom::{Angle, Line, PolyLine, Pt2D}; use geom::{Angle, HashablePt2D, Line, PolyLine, Pt2D};
use std::collections::HashMap; use std::collections::HashMap;
use std::marker; use std::marker;
@ -122,17 +123,6 @@ fn degenerate_twoway(
} }
} }
// Temporary until Pt2D has proper resolution.
fn approx_dedupe(pts: Vec<Pt2D>) -> Vec<Pt2D> {
let mut result: Vec<Pt2D> = Vec::new();
for pt in pts {
if result.is_empty() || !result.last().unwrap().approx_eq(pt) {
result.push(pt);
}
}
result
}
fn make_simple_degenerate( fn make_simple_degenerate(
roads: &mut Vec<Road>, roads: &mut Vec<Road>,
i: IntersectionID, i: IntersectionID,
@ -265,9 +255,35 @@ fn generalized_trim_back(
endpoints.push(r.center_pts.shift_left(back_width).first_pt()); endpoints.push(r.center_pts.shift_left(back_width).first_pt());
} }
} }
// Include collisions between polylines of adjacent roads, so the polygon doesn't cover area
// not originally covered by the thick road bands.
for idx in 0..lines.len() as isize {
let (_, _, fwd_pl, back_pl) = wraparound_get(&lines, idx);
let (_, _, adj_back_pl, _) = wraparound_get(&lines, idx + 1);
let (_, _, _, adj_fwd_pl) = wraparound_get(&lines, idx - 1);
if let Some((hit, _)) = fwd_pl.intersection(adj_fwd_pl) {
endpoints.push(hit);
}
if let Some((hit, _)) = back_pl.intersection(adj_back_pl) {
endpoints.push(hit);
}
}
endpoints.sort_by_key(|pt| HashablePt2D::from(*pt));
endpoints = approx_dedupe(endpoints); endpoints = approx_dedupe(endpoints);
let center = Pt2D::center(&endpoints); let center = Pt2D::center(&endpoints);
endpoints.sort_by_key(|pt| Line::new(center, *pt).angle().normalized_degrees() as i64); endpoints.sort_by_key(|pt| Line::new(center, *pt).angle().normalized_degrees() as i64);
endpoints endpoints
} }
// Temporary until Pt2D has proper resolution.
fn approx_dedupe(pts: Vec<Pt2D>) -> Vec<Pt2D> {
let mut result: Vec<Pt2D> = Vec::new();
for pt in pts {
if result.is_empty() || !result.last().unwrap().approx_eq(pt, 1.0 * si::M) {
result.push(pt);
}
}
result
}