mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-24 09:24:26 +03:00
using Warn in all of geom
This commit is contained in:
parent
1848387ef0
commit
c2791a6ead
@ -88,6 +88,13 @@ impl<T> Warn<T> {
|
||||
self.value
|
||||
}
|
||||
|
||||
pub fn map<O, F: Fn(T) -> O>(self, f: F) -> Warn<O> {
|
||||
Warn {
|
||||
value: f(self.value),
|
||||
warnings: self.warnings,
|
||||
}
|
||||
}
|
||||
|
||||
/*pub fn get_and_append<X>(self, other: &mut Warn<X>) -> T {
|
||||
other.warnings.extend(self.warnings);
|
||||
self.value
|
||||
@ -105,9 +112,9 @@ impl<T> Warn<T> {
|
||||
}
|
||||
|
||||
impl Warn<()> {
|
||||
pub fn empty() -> Warn<()> {
|
||||
Warn::ok(())
|
||||
}
|
||||
/*pub fn empty_warnings(warnings: Vec<String>) -> Warn<()> {
|
||||
Warn::warnings((), warnings)
|
||||
}*/
|
||||
|
||||
/*pub fn add_warning(&mut self, line: String) {
|
||||
self.warnings.push(line);
|
||||
|
@ -134,8 +134,8 @@ fn use_parking_hints(
|
||||
FindClosest::new(&gps_bounds.to_bounds());
|
||||
for (id, r) in &map.roads {
|
||||
let pts = PolyLine::new(gps_bounds.must_convert(&r.points));
|
||||
closest.add((*id, true), &pts.shift_right(LANE_THICKNESS));
|
||||
closest.add((*id, false), &pts.shift_left(LANE_THICKNESS));
|
||||
closest.add((*id, true), &pts.shift_right(LANE_THICKNESS).get(timer));
|
||||
closest.add((*id, false), &pts.shift_left(LANE_THICKNESS).get(timer));
|
||||
}
|
||||
|
||||
'SHAPE: for s in shapes.shapes.into_iter() {
|
||||
|
@ -278,7 +278,7 @@ fn extrude_to_boundary(boundary_polygon: &Vec<LonLat>, result: &mut Vec<LonLat>)
|
||||
);
|
||||
|
||||
let slice1 = find_slice(boundary_polygon, closest_to_last, closest_to_first);
|
||||
let mut backwards_boundary: Vec<LonLat> = boundary_polygon.iter().cloned().collect();
|
||||
let mut backwards_boundary: Vec<LonLat> = boundary_polygon.to_vec();
|
||||
backwards_boundary.reverse();
|
||||
let slice2 = find_slice(&backwards_boundary, closest_to_last, closest_to_first);
|
||||
if slice_len(&slice1) <= slice_len(&slice2) {
|
||||
|
@ -122,6 +122,7 @@ fn load_initial_map(filename: &str, canvas: &mut Canvas, prerender: &Prerender)
|
||||
ID::HalfRoad(r.id, true),
|
||||
r.trimmed_center_pts
|
||||
.shift_right(r.fwd_width / 2.0)
|
||||
.unwrap()
|
||||
.make_polygons(r.fwd_width),
|
||||
Color::grey(0.8),
|
||||
Text::from_line(format!(
|
||||
@ -137,6 +138,7 @@ fn load_initial_map(filename: &str, canvas: &mut Canvas, prerender: &Prerender)
|
||||
ID::HalfRoad(r.id, false),
|
||||
r.trimmed_center_pts
|
||||
.shift_left(r.back_width / 2.0)
|
||||
.unwrap()
|
||||
.make_polygons(r.back_width),
|
||||
Color::grey(0.6),
|
||||
Text::from_line(format!(
|
||||
|
@ -46,6 +46,7 @@ impl NonblockingPlugin for ShowOriginalRoads {
|
||||
.get_def("original road forwards", Color::RED.alpha(0.5)),
|
||||
&r.original_center_pts
|
||||
.shift_right(width_right / 2.0)
|
||||
.unwrap()
|
||||
.make_polygons(width_right),
|
||||
);
|
||||
}
|
||||
@ -55,6 +56,7 @@ impl NonblockingPlugin for ShowOriginalRoads {
|
||||
.get_def("original road backwards", Color::BLUE.alpha(0.5)),
|
||||
&r.original_center_pts
|
||||
.shift_left(width_left / 2.0)
|
||||
.unwrap()
|
||||
.make_polygons(width_left),
|
||||
);
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ impl Interval {
|
||||
let numer = t_1 * v_1 - t_3 * v_3 - x_1 + x_3;
|
||||
let denom = v_1 - v_3;
|
||||
Duration::seconds(numer / denom)
|
||||
} else if a_1 == a_3 {
|
||||
} else if (a_1 - a_3).abs() < std::f64::EPSILON {
|
||||
// Sometimes exactly the same acceleration happens.
|
||||
let numer = a_3 * t_1.powi(2) - a_3 * t_3.powi(2) - 2.0 * t_1 * v_1
|
||||
+ 2.0 * t_3 * v_3
|
||||
|
@ -83,7 +83,7 @@ impl World {
|
||||
if num_waiting > 0 {
|
||||
// Short lanes exist
|
||||
let start = (l.length()
|
||||
- (num_waiting as f64) * (VEHICLE_LENGTH + FOLLOWING_DISTANCE))
|
||||
- f64::from(num_waiting) * (VEHICLE_LENGTH + FOLLOWING_DISTANCE))
|
||||
.max(Distance::ZERO);
|
||||
g.draw_polygon(
|
||||
WAITING,
|
||||
@ -100,7 +100,7 @@ impl World {
|
||||
&l.lane_center_pts
|
||||
.slice(
|
||||
Distance::ZERO,
|
||||
(num_freeflow as f64) * (VEHICLE_LENGTH + FOLLOWING_DISTANCE),
|
||||
f64::from(num_freeflow) * (VEHICLE_LENGTH + FOLLOWING_DISTANCE),
|
||||
)
|
||||
.unwrap()
|
||||
.0
|
||||
@ -179,7 +179,7 @@ impl World {
|
||||
.unwrap()
|
||||
.cars
|
||||
.push_back(Car {
|
||||
id: id,
|
||||
id,
|
||||
max_speed,
|
||||
path: VecDeque::from(path.clone()),
|
||||
state: CarState::CrossingLane(TimeInterval {
|
||||
@ -198,22 +198,18 @@ impl World {
|
||||
// Promote CrossingLane to Queued.
|
||||
for queue in self.queues.values_mut() {
|
||||
for car in queue.cars.iter_mut() {
|
||||
match car.state {
|
||||
CarState::CrossingLane(ref interval) => {
|
||||
if let CarState::CrossingLane(ref interval) = car.state {
|
||||
if time > interval.end {
|
||||
car.state = CarState::Queued;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Delete head cars that're completely done.
|
||||
for queue in self.queues.values_mut() {
|
||||
while !queue.is_empty() {
|
||||
match queue.cars[0].state {
|
||||
CarState::Queued => {
|
||||
if let CarState::Queued = queue.cars[0].state {
|
||||
if queue.cars[0].path.len() == 1 {
|
||||
queue.cars.pop_front();
|
||||
// TODO Should have some brief delay to creep forwards VEHICLE_LENGTH +
|
||||
@ -221,8 +217,6 @@ impl World {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -235,12 +229,9 @@ impl World {
|
||||
continue;
|
||||
}
|
||||
let car = &queue.cars[0];
|
||||
match car.state {
|
||||
CarState::Queued => {
|
||||
if let CarState::Queued = car.state {
|
||||
cars_ready_to_turn.push((queue.id, car.path[1].as_turn()));
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
|
||||
// Lane->Turn transitions
|
||||
|
@ -44,7 +44,7 @@ impl Queue {
|
||||
CarState::CrossingLane(ref i) => {
|
||||
let bound = last_car_back
|
||||
.map(|b| b - FOLLOWING_DISTANCE)
|
||||
.unwrap_or(l.length());
|
||||
.unwrap_or_else(|| l.length());
|
||||
(i.percent(time) * bound, FREEFLOW)
|
||||
}
|
||||
CarState::CrossingTurn(_) => unreachable!(),
|
||||
|
@ -171,7 +171,7 @@ impl RoadHeatmap {
|
||||
Color::RED
|
||||
};
|
||||
// TODO Inefficient!
|
||||
g.draw_polygon(color, &DrawRoad::get_thick(ctx.map.get_r(*r)));
|
||||
g.draw_polygon(color, &DrawRoad::get_thick(ctx.map.get_r(*r)).unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ impl DrawLane {
|
||||
draw.extend(calculate_parking_lines(lane, cs));
|
||||
}
|
||||
LaneType::Driving | LaneType::Bus => {
|
||||
draw.extend(calculate_driving_lines(lane, road, cs));
|
||||
draw.extend(calculate_driving_lines(lane, road, cs, timer));
|
||||
draw.extend(calculate_turn_markings(map, lane, cs, timer));
|
||||
}
|
||||
LaneType::Biking => {}
|
||||
@ -182,7 +182,12 @@ fn calculate_parking_lines(lane: &Lane, cs: &ColorScheme) -> Vec<(Color, Polygon
|
||||
result
|
||||
}
|
||||
|
||||
fn calculate_driving_lines(lane: &Lane, parent: &Road, cs: &ColorScheme) -> Vec<(Color, Polygon)> {
|
||||
fn calculate_driving_lines(
|
||||
lane: &Lane,
|
||||
parent: &Road,
|
||||
cs: &ColorScheme,
|
||||
timer: &mut Timer,
|
||||
) -> Vec<(Color, Polygon)> {
|
||||
// The leftmost lanes don't have dashed white lines.
|
||||
if parent.dir_and_offset(lane.id).1 == 0 {
|
||||
return Vec::new();
|
||||
@ -191,7 +196,10 @@ fn calculate_driving_lines(lane: &Lane, parent: &Road, cs: &ColorScheme) -> Vec<
|
||||
let dash_separation = Distance::meters(1.5);
|
||||
let dash_len = Distance::meters(1.0);
|
||||
|
||||
let lane_edge_pts = lane.lane_center_pts.shift_left(LANE_THICKNESS / 2.0);
|
||||
let lane_edge_pts = lane
|
||||
.lane_center_pts
|
||||
.shift_left(LANE_THICKNESS / 2.0)
|
||||
.get(timer);
|
||||
if lane_edge_pts.length() < dash_separation * 2.0 {
|
||||
return Vec::new();
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ impl DrawMap {
|
||||
let mut all_roads: Vec<Polygon> = Vec::new();
|
||||
for r in map.all_roads() {
|
||||
timer.next();
|
||||
let (draw, poly) = DrawRoad::new(r, cs, prerender);
|
||||
let (draw, poly) = DrawRoad::new(r, cs, prerender, timer);
|
||||
roads.push(draw);
|
||||
all_roads.push(poly);
|
||||
}
|
||||
@ -159,8 +159,14 @@ impl DrawMap {
|
||||
// Match shapes with the nearest road + direction (true for forwards)
|
||||
let mut closest: FindClosest<(RoadID, bool)> = FindClosest::new(&map.get_bounds());
|
||||
for r in map.all_roads().iter() {
|
||||
closest.add((r.id, true), &r.center_pts.shift_right(LANE_THICKNESS));
|
||||
closest.add((r.id, false), &r.center_pts.shift_left(LANE_THICKNESS));
|
||||
closest.add(
|
||||
(r.id, true),
|
||||
&r.center_pts.shift_right(LANE_THICKNESS).get(timer),
|
||||
);
|
||||
closest.add(
|
||||
(r.id, false),
|
||||
&r.center_pts.shift_left(LANE_THICKNESS).get(timer),
|
||||
);
|
||||
}
|
||||
|
||||
let gps_bounds = map.get_gps_bounds();
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::colors::ColorScheme;
|
||||
use crate::objects::{DrawCtx, ID};
|
||||
use crate::render::{RenderOptions, Renderable, BIG_ARROW_THICKNESS};
|
||||
use abstutil::{Timer, Warn};
|
||||
use ezgui::{Color, Drawable, GfxCtx, Prerender};
|
||||
use geom::{Bounds, Polygon, Pt2D};
|
||||
use map_model::{Map, Road, RoadID, LANE_THICKNESS};
|
||||
@ -15,8 +16,13 @@ pub struct DrawRoad {
|
||||
}
|
||||
|
||||
impl DrawRoad {
|
||||
pub fn new(r: &Road, cs: &ColorScheme, prerender: &Prerender) -> (DrawRoad, Polygon) {
|
||||
let thick = DrawRoad::get_thick(r);
|
||||
pub fn new(
|
||||
r: &Road,
|
||||
cs: &ColorScheme,
|
||||
prerender: &Prerender,
|
||||
timer: &mut Timer,
|
||||
) -> (DrawRoad, Polygon) {
|
||||
let thick = DrawRoad::get_thick(r).get(timer);
|
||||
(
|
||||
DrawRoad {
|
||||
id: r.id,
|
||||
@ -31,7 +37,7 @@ impl DrawRoad {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_thick(r: &Road) -> Polygon {
|
||||
pub fn get_thick(r: &Road) -> Warn<Polygon> {
|
||||
// TODO Should be a less tedious way to do this
|
||||
let width_right = (r.children_forwards.len() as f64) * LANE_THICKNESS;
|
||||
let width_left = (r.children_backwards.len() as f64) * LANE_THICKNESS;
|
||||
@ -39,11 +45,11 @@ impl DrawRoad {
|
||||
if width_right >= width_left {
|
||||
r.center_pts
|
||||
.shift_right((width_right - width_left) / 2.0)
|
||||
.make_polygons(total_width)
|
||||
.map(|pl| pl.make_polygons(total_width))
|
||||
} else {
|
||||
r.center_pts
|
||||
.shift_left((width_left - width_right) / 2.0)
|
||||
.make_polygons(total_width)
|
||||
.map(|pl| pl.make_polygons(total_width))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::{
|
||||
Angle, Bounds, Distance, HashablePt2D, InfiniteLine, Line, Polygon, Pt2D, EPSILON_DIST,
|
||||
};
|
||||
use abstutil::Warn;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::collections::HashSet;
|
||||
use std::fmt;
|
||||
@ -242,18 +243,18 @@ impl PolyLine {
|
||||
Some(PolyLine::new(self.pts[0..self.pts.len() - 1].to_vec()))
|
||||
}
|
||||
|
||||
pub fn shift_right(&self, width: Distance) -> PolyLine {
|
||||
pub fn shift_right(&self, width: Distance) -> Warn<PolyLine> {
|
||||
self.shift_with_corrections(width)
|
||||
}
|
||||
|
||||
pub fn shift_left(&self, width: Distance) -> PolyLine {
|
||||
pub fn shift_left(&self, width: Distance) -> Warn<PolyLine> {
|
||||
self.shift_with_corrections(-width)
|
||||
}
|
||||
|
||||
// Things to remember about shifting polylines:
|
||||
// - the length before and after probably don't match up
|
||||
// - the number of points will match
|
||||
fn shift_with_corrections(&self, width: Distance) -> PolyLine {
|
||||
fn shift_with_corrections(&self, width: Distance) -> Warn<PolyLine> {
|
||||
let result = PolyLine::new(Pt2D::approx_dedupe(
|
||||
self.shift_with_sharp_angles(width),
|
||||
EPSILON_DIST,
|
||||
@ -263,11 +264,7 @@ impl PolyLine {
|
||||
} else {
|
||||
result
|
||||
};
|
||||
// TODO The warning is very spammy. Known issue, silence for now.
|
||||
if false {
|
||||
check_angles(self, &fixed);
|
||||
}
|
||||
fixed
|
||||
check_angles(self, fixed)
|
||||
}
|
||||
|
||||
fn shift_with_sharp_angles(&self, width: Distance) -> Vec<Pt2D> {
|
||||
@ -529,16 +526,18 @@ fn fix_angles(orig: &PolyLine, result: PolyLine) -> PolyLine {
|
||||
PolyLine::new(pts)
|
||||
}
|
||||
|
||||
fn check_angles(a: &PolyLine, b: &PolyLine) {
|
||||
for (orig_l, shifted_l) in a.lines().iter().zip(b.lines().iter()) {
|
||||
fn check_angles(orig: &PolyLine, fixed: PolyLine) -> Warn<PolyLine> {
|
||||
let mut warnings = Vec::new();
|
||||
for (orig_l, shifted_l) in orig.lines().iter().zip(fixed.lines().iter()) {
|
||||
let orig_angle = orig_l.angle();
|
||||
let shifted_angle = shifted_l.angle();
|
||||
|
||||
if !orig_angle.approx_eq(shifted_angle, 1.0) {
|
||||
println!(
|
||||
"BAD! Points changed angles from {} to {}",
|
||||
warnings.push(format!(
|
||||
"Points changed angles from {} to {} during polyline shifting",
|
||||
orig_angle, shifted_angle
|
||||
);
|
||||
));
|
||||
}
|
||||
}
|
||||
Warn::warnings(fixed, warnings)
|
||||
}
|
||||
|
@ -111,7 +111,9 @@ pub fn make_half_map(
|
||||
// TODO need to factor in yellow center lines (but what's the right thing to even do?
|
||||
// Reverse points for British-style driving on the left
|
||||
let width = LANE_THICKNESS * (0.5 + (offset as f64));
|
||||
let lane_center_pts = unshifted_pts.shift_right(width);
|
||||
let lane_center_pts = unshifted_pts
|
||||
.shift_right(width)
|
||||
.with_context(timer, format!("shift for {}", id));
|
||||
|
||||
half_map.lanes.push(Lane {
|
||||
id,
|
||||
|
@ -41,7 +41,7 @@ pub fn fix_ramps(m: &mut InitialMap, timer: &mut Timer) {
|
||||
}
|
||||
|
||||
for (r, i) in fixme {
|
||||
if fix_ramp(m, r, i) {
|
||||
if fix_ramp(m, r, i, timer) {
|
||||
info!("Fixed ramp {} crossing {}", r, i);
|
||||
} else {
|
||||
info!("{} crosses {} strangely, but didn't change anything", r, i);
|
||||
@ -75,7 +75,12 @@ fn floodfill(m: &InitialMap, start: StableIntersectionID, steps: usize) -> HashS
|
||||
seen
|
||||
}
|
||||
|
||||
fn fix_ramp(m: &mut InitialMap, ramp: StableRoadID, new_src: StableIntersectionID) -> bool {
|
||||
fn fix_ramp(
|
||||
m: &mut InitialMap,
|
||||
ramp: StableRoadID,
|
||||
new_src: StableIntersectionID,
|
||||
timer: &mut Timer,
|
||||
) -> bool {
|
||||
// Trace backwards...
|
||||
let mut delete_roads: Vec<StableRoadID> = Vec::new();
|
||||
let mut delete_intersections: Vec<StableIntersectionID> = Vec::new();
|
||||
@ -104,7 +109,7 @@ fn fix_ramp(m: &mut InitialMap, ramp: StableRoadID, new_src: StableIntersectionI
|
||||
if let Some(last_road) = delete_roads.last() {
|
||||
let mut i = m.intersections.get_mut(&last_normal_intersection).unwrap();
|
||||
i.roads.remove(&last_road);
|
||||
i.polygon = geometry::intersection_polygon(i, &mut m.roads);
|
||||
i.polygon = geometry::intersection_polygon(i, &mut m.roads, timer);
|
||||
} else {
|
||||
// TODO Not really sure why, but when there's not a road in between, don't apply the fix.
|
||||
return false;
|
||||
@ -120,7 +125,7 @@ fn fix_ramp(m: &mut InitialMap, ramp: StableRoadID, new_src: StableIntersectionI
|
||||
m.roads.get_mut(&ramp).unwrap().src_i = new_src;
|
||||
let mut i = m.intersections.get_mut(&new_src).unwrap();
|
||||
i.roads.insert(ramp);
|
||||
i.polygon = geometry::intersection_polygon(i, &mut m.roads);
|
||||
i.polygon = geometry::intersection_polygon(i, &mut m.roads, timer);
|
||||
}
|
||||
true
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::make::initial::{Intersection, Road};
|
||||
use crate::raw_data::{StableIntersectionID, StableRoadID};
|
||||
use abstutil::wraparound_get;
|
||||
use abstutil::{wraparound_get, Timer};
|
||||
use geom::{Distance, HashablePt2D, Line, PolyLine, Pt2D};
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
|
||||
@ -11,6 +11,7 @@ const DEGENERATE_INTERSECTION_HALF_LENGTH: Distance = Distance::const_meters(5.0
|
||||
pub fn intersection_polygon(
|
||||
i: &Intersection,
|
||||
roads: &mut BTreeMap<StableRoadID, Road>,
|
||||
timer: &mut Timer,
|
||||
) -> Vec<Pt2D> {
|
||||
let mut road_endpts: Vec<Pt2D> = Vec::new();
|
||||
|
||||
@ -35,8 +36,12 @@ pub fn intersection_polygon(
|
||||
panic!("Incident road {} doesn't have an endpoint at {}", id, i.id);
|
||||
};
|
||||
|
||||
let pl_normal = line.shift_right(width_normal);
|
||||
let pl_reverse = line.shift_left(width_reverse);
|
||||
let pl_normal = line
|
||||
.shift_right(width_normal)
|
||||
.with_context(timer, format!("pl_normal {}", r.id));
|
||||
let pl_reverse = line
|
||||
.shift_left(width_reverse)
|
||||
.with_context(timer, format!("pl_reverse {}", r.id));
|
||||
(*id, line.last_line(), pl_normal, pl_reverse)
|
||||
})
|
||||
.collect();
|
||||
@ -56,7 +61,7 @@ pub fn intersection_polygon(
|
||||
let mut endpoints = if lines.len() == 1 {
|
||||
deadend(roads, i.id, &lines)
|
||||
} else {
|
||||
generalized_trim_back(roads, i.id, &lines)
|
||||
generalized_trim_back(roads, i.id, &lines, timer)
|
||||
};
|
||||
|
||||
// Close off the polygon
|
||||
@ -75,6 +80,7 @@ fn generalized_trim_back(
|
||||
roads: &mut BTreeMap<StableRoadID, Road>,
|
||||
i: StableIntersectionID,
|
||||
lines: &Vec<(StableRoadID, Line, PolyLine, PolyLine)>,
|
||||
timer: &mut Timer,
|
||||
) -> Vec<Pt2D> {
|
||||
let mut road_lines: Vec<(StableRoadID, PolyLine, PolyLine)> = Vec::new();
|
||||
for (r, _, pl1, pl2) in lines {
|
||||
@ -228,11 +234,31 @@ fn generalized_trim_back(
|
||||
|
||||
// Shift those final centers out again to find the main endpoints for the polygon.
|
||||
if r.dst_i == i {
|
||||
endpoints.push(r.trimmed_center_pts.shift_right(r.fwd_width).last_pt());
|
||||
endpoints.push(r.trimmed_center_pts.shift_left(r.back_width).last_pt());
|
||||
endpoints.push(
|
||||
r.trimmed_center_pts
|
||||
.shift_right(r.fwd_width)
|
||||
.get(timer)
|
||||
.last_pt(),
|
||||
);
|
||||
endpoints.push(
|
||||
r.trimmed_center_pts
|
||||
.shift_left(r.back_width)
|
||||
.get(timer)
|
||||
.last_pt(),
|
||||
);
|
||||
} else {
|
||||
endpoints.push(r.trimmed_center_pts.shift_left(r.back_width).first_pt());
|
||||
endpoints.push(r.trimmed_center_pts.shift_right(r.fwd_width).first_pt());
|
||||
endpoints.push(
|
||||
r.trimmed_center_pts
|
||||
.shift_left(r.back_width)
|
||||
.get(timer)
|
||||
.first_pt(),
|
||||
);
|
||||
endpoints.push(
|
||||
r.trimmed_center_pts
|
||||
.shift_right(r.fwd_width)
|
||||
.get(timer)
|
||||
.first_pt(),
|
||||
);
|
||||
}
|
||||
|
||||
if back_pl.length() >= geom::EPSILON_DIST * 3.0
|
||||
|
@ -1,26 +1,26 @@
|
||||
use crate::make::initial::{geometry, InitialMap};
|
||||
use crate::raw_data::{StableIntersectionID, StableRoadID};
|
||||
use abstutil::note;
|
||||
use abstutil::Timer;
|
||||
use geom::Distance;
|
||||
use std::collections::HashSet;
|
||||
|
||||
pub fn short_roads(map: &mut InitialMap) {
|
||||
pub fn short_roads(map: &mut InitialMap, timer: &mut Timer) {
|
||||
if false {
|
||||
// I228
|
||||
merge(map, StableRoadID(311));
|
||||
merge(map, StableRoadID(311), timer);
|
||||
|
||||
// I201
|
||||
merge(map, StableRoadID(240));
|
||||
merge(map, StableRoadID(240), timer);
|
||||
|
||||
// I37
|
||||
merge(map, StableRoadID(91));
|
||||
merge(map, StableRoadID(91), timer);
|
||||
|
||||
// I40
|
||||
merge(map, StableRoadID(59));
|
||||
merge(map, StableRoadID(59), timer);
|
||||
|
||||
// I25
|
||||
merge(map, StableRoadID(389));
|
||||
merge(map, StableRoadID(22));
|
||||
merge(map, StableRoadID(389), timer);
|
||||
merge(map, StableRoadID(22), timer);
|
||||
}
|
||||
|
||||
if false {
|
||||
@ -36,30 +36,34 @@ pub fn short_roads(map: &mut InitialMap) {
|
||||
.values()
|
||||
.find(|r| r.trimmed_center_pts.length() < Distance::meters(5.0))
|
||||
{
|
||||
look_at.insert(merge(map, r.id));
|
||||
look_at.insert(merge(map, r.id, timer));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
note(format!(
|
||||
timer.note(format!(
|
||||
"Deleted {} tiny roads",
|
||||
orig_count - map.roads.len()
|
||||
));
|
||||
for id in look_at {
|
||||
if map.intersections.contains_key(&id) {
|
||||
note(format!("Check for merged roads near {}", id));
|
||||
timer.note(format!("Check for merged roads near {}", id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the retained intersection.
|
||||
fn merge(map: &mut InitialMap, merge_road: StableRoadID) -> StableIntersectionID {
|
||||
fn merge(
|
||||
map: &mut InitialMap,
|
||||
merge_road: StableRoadID,
|
||||
timer: &mut Timer,
|
||||
) -> StableIntersectionID {
|
||||
// Arbitrarily kill off the first intersection and keep the second one.
|
||||
let (delete_i, keep_i) = {
|
||||
let r = &map.roads[&merge_road];
|
||||
note(format!(
|
||||
timer.note(format!(
|
||||
"Deleting {}, which has original length {} and trimmed length {}",
|
||||
merge_road,
|
||||
r.original_center_pts.length(),
|
||||
@ -139,7 +143,7 @@ fn merge(map: &mut InitialMap, merge_road: StableRoadID) -> StableIntersectionID
|
||||
map.save(None);
|
||||
|
||||
let mut i = map.intersections.get_mut(&keep_i).unwrap();
|
||||
i.polygon = geometry::intersection_polygon(i, &mut map.roads);
|
||||
i.polygon = geometry::intersection_polygon(i, &mut map.roads, timer);
|
||||
// Show the final results of fixing this area
|
||||
map.save(None);
|
||||
|
||||
|
@ -144,12 +144,12 @@ impl InitialMap {
|
||||
for i in m.intersections.values_mut() {
|
||||
timer.next();
|
||||
|
||||
i.polygon = geometry::intersection_polygon(i, &mut m.roads);
|
||||
i.polygon = geometry::intersection_polygon(i, &mut m.roads, timer);
|
||||
}
|
||||
|
||||
fix_ramps::fix_ramps(&mut m, timer);
|
||||
|
||||
merge::short_roads(&mut m);
|
||||
merge::short_roads(&mut m, timer);
|
||||
|
||||
m
|
||||
}
|
||||
|
@ -34,14 +34,14 @@ pub fn run(g: &mut GfxCtx) {
|
||||
(north_yellow, RelatedColors::new(0.0, 1.0, 0.0)),
|
||||
(south_yellow, RelatedColors::new(0.0, 0.0, 1.0)),
|
||||
] {
|
||||
let lane1_in = yellow_line.shift_right(shift1_width);
|
||||
let lane1_in = yellow_line.shift_right(shift1_width).unwrap();
|
||||
draw_lane(g, &lane1_in, colors.next().unwrap());
|
||||
let lane2_in = yellow_line.shift_right(shift2_width);
|
||||
let lane2_in = yellow_line.shift_right(shift2_width).unwrap();
|
||||
draw_lane(g, &lane2_in, colors.next().unwrap());
|
||||
|
||||
let lane1_out = yellow_line.reversed().shift_right(shift1_width);
|
||||
let lane1_out = yellow_line.reversed().shift_right(shift1_width).unwrap();
|
||||
draw_lane(g, &lane1_out, colors.next().unwrap());
|
||||
let lane2_out = yellow_line.reversed().shift_right(shift2_width);
|
||||
let lane2_out = yellow_line.reversed().shift_right(shift2_width).unwrap();
|
||||
draw_lane(g, &lane2_out, colors.next().unwrap());
|
||||
|
||||
draw_polyline(g, &yellow_line, thin, YELLOW);
|
||||
|
@ -31,13 +31,13 @@ pub fn run(g: &mut GfxCtx, labels: &mut Vec<(Pt2D, String)>) {
|
||||
g.draw_polygon(BLACK, ¢er_pts.make_polygons(width));
|
||||
|
||||
// TODO colored labels!
|
||||
let side1 = center_pts.shift_right(width / 2.0);
|
||||
let side1 = center_pts.shift_right(width / 2.0).unwrap();
|
||||
//draw_polyline(g, &side1, thin, BLUE);
|
||||
for (idx, pt) in side1.points().iter().enumerate() {
|
||||
labels.push((*pt, format!("L{}", idx + 1)));
|
||||
}
|
||||
|
||||
let side2 = center_pts.shift_left(width / 2.0);
|
||||
let side2 = center_pts.shift_left(width / 2.0).unwrap();
|
||||
//draw_polyline(g, &side2, thin, GREEN);
|
||||
for (idx, pt) in side2.points().iter().enumerate() {
|
||||
labels.push((*pt, format!("R{}", idx + 1)));
|
||||
|
@ -37,20 +37,20 @@ pub fn run(p3_offset: (f64, f64), g: &mut GfxCtx, labels: &mut Vec<(Pt2D, String
|
||||
g.draw_polygon(BLACK, &pts.make_polygons(shift_away));
|
||||
|
||||
// Two lanes on one side of the road
|
||||
let l1_pts = pts.shift_right(shift_away);
|
||||
let l1_pts = pts.shift_right(shift_away).unwrap();
|
||||
for (idx, pt) in l1_pts.points().iter().enumerate() {
|
||||
labels.push((*pt, format!("l1_p{}", idx + 1)));
|
||||
}
|
||||
draw_polyline(g, &l1_pts, thin, GREEN);
|
||||
|
||||
let l2_pts = pts.shift_right(shift_away * 2.0);
|
||||
let l2_pts = pts.shift_right(shift_away * 2.0).unwrap();
|
||||
for (idx, pt) in l2_pts.points().iter().enumerate() {
|
||||
labels.push((*pt, format!("l2_p{}", idx + 1)));
|
||||
}
|
||||
draw_polyline(g, &l2_pts, thin, GREEN);
|
||||
|
||||
// Other side
|
||||
let l3_pts = pts.reversed().shift_right(shift_away);
|
||||
let l3_pts = pts.reversed().shift_right(shift_away).unwrap();
|
||||
for (idx, pt) in l3_pts.points().iter().enumerate() {
|
||||
labels.push((*pt, format!("l3_p{}", idx + 1)));
|
||||
}
|
||||
|
@ -920,7 +920,9 @@ impl DrivingSimState {
|
||||
1.0 - progress
|
||||
};
|
||||
// TODO we're assuming the parking lane is to the right of us!
|
||||
base_body.shift_right(LANE_THICKNESS * project_away_ratio)
|
||||
base_body
|
||||
.shift_right(LANE_THICKNESS * project_away_ratio)
|
||||
.unwrap()
|
||||
} else {
|
||||
base_body
|
||||
};
|
||||
|
@ -77,10 +77,10 @@ impl Road {
|
||||
]);
|
||||
if direction {
|
||||
let width = LANE_THICKNESS * (self.lanes.fwd.len() as f64);
|
||||
pl.shift_right(width / 2.0).make_polygons(width)
|
||||
pl.shift_right(width / 2.0).unwrap().make_polygons(width)
|
||||
} else {
|
||||
let width = LANE_THICKNESS * (self.lanes.back.len() as f64);
|
||||
pl.shift_left(width / 2.0).make_polygons(width)
|
||||
pl.shift_left(width / 2.0).unwrap().make_polygons(width)
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,6 +93,7 @@ impl Road {
|
||||
for (idx, lt) in self.lanes.fwd.iter().enumerate() {
|
||||
let polygon = base
|
||||
.shift_right(LANE_THICKNESS * ((idx as f64) + 0.5))
|
||||
.unwrap()
|
||||
.make_polygons(LANE_THICKNESS);
|
||||
g.draw_polygon(
|
||||
if highlight_fwd {
|
||||
@ -106,6 +107,7 @@ impl Road {
|
||||
for (idx, lt) in self.lanes.back.iter().enumerate() {
|
||||
let polygon = base
|
||||
.shift_left(LANE_THICKNESS * ((idx as f64) + 0.5))
|
||||
.unwrap()
|
||||
.make_polygons(LANE_THICKNESS);
|
||||
g.draw_polygon(
|
||||
if highlight_back {
|
||||
|
Loading…
Reference in New Issue
Block a user