remove all the polyline shifting/polygon variants that might fail

This commit is contained in:
Dustin Carlino 2019-01-15 15:02:51 -08:00
parent 57665c9325
commit e8e119dbbf
24 changed files with 86 additions and 265 deletions

View File

@ -140,8 +140,8 @@ fn use_parking_hints(map: &mut raw_data::Map, shapes: ExtraShapes, gps_bounds: &
.collect(), .collect(),
); );
closest.add((idx, true), &pts.shift_blindly_right(LANE_THICKNESS)); closest.add((idx, true), &pts.shift_right(LANE_THICKNESS));
closest.add((idx, false), &pts.shift_blindly_left(LANE_THICKNESS)); closest.add((idx, false), &pts.shift_left(LANE_THICKNESS));
} }
'SHAPE: for s in shapes.shapes.into_iter() { 'SHAPE: for s in shapes.shapes.into_iter() {

View File

@ -59,14 +59,14 @@ impl Plugin for DiffTripState {
if let Some(t) = &self.primary_route { if let Some(t) = &self.primary_route {
g.draw_polygon( g.draw_polygon(
ctx.cs.get_def("primary agent route", Color::RED.alpha(0.5)), ctx.cs.get_def("primary agent route", Color::RED.alpha(0.5)),
&t.make_polygons_blindly(LANE_THICKNESS), &t.make_polygons(LANE_THICKNESS),
); );
} }
if let Some(t) = &self.secondary_route { if let Some(t) = &self.secondary_route {
g.draw_polygon( g.draw_polygon(
ctx.cs ctx.cs
.get_def("secondary agent route", Color::BLUE.alpha(0.5)), .get_def("secondary agent route", Color::BLUE.alpha(0.5)),
&t.make_polygons_blindly(LANE_THICKNESS), &t.make_polygons(LANE_THICKNESS),
); );
} }
} }

View File

@ -67,15 +67,12 @@ impl Plugin for ShowRouteState {
ShowRouteState::Active(_, _, Some(ref trace)) => { ShowRouteState::Active(_, _, Some(ref trace)) => {
g.draw_polygon( g.draw_polygon(
ctx.cs.get_def("route", Color::RED.alpha(0.8)), ctx.cs.get_def("route", Color::RED.alpha(0.8)),
&trace.make_polygons_blindly(LANE_THICKNESS), &trace.make_polygons(LANE_THICKNESS),
); );
} }
ShowRouteState::DebugAllRoutes(_, ref traces) => { ShowRouteState::DebugAllRoutes(_, ref traces) => {
for t in traces { for t in traces {
g.draw_polygon( g.draw_polygon(ctx.cs.get("route"), &t.make_polygons(LANE_THICKNESS));
ctx.cs.get("route"),
&t.make_polygons_blindly(LANE_THICKNESS),
);
} }
} }
_ => {} _ => {}

View File

@ -17,13 +17,11 @@ pub struct DrawBike {
impl DrawBike { impl DrawBike {
pub fn new(input: DrawCarInput) -> DrawBike { pub fn new(input: DrawCarInput) -> DrawBike {
let stopping_buffer = input let stopping_buffer = input.stopping_trace.map(|t| t.make_polygons(BIKE_WIDTH));
.stopping_trace
.map(|t| t.make_polygons_blindly(BIKE_WIDTH));
DrawBike { DrawBike {
id: input.id, id: input.id,
polygon: input.body.make_polygons_blindly(BIKE_WIDTH), polygon: input.body.make_polygons(BIKE_WIDTH),
stopping_buffer, stopping_buffer,
state: input.state, state: input.state,
} }

View File

@ -27,7 +27,7 @@ impl DrawBusStop {
.map(|(pt, _)| pt) .map(|(pt, _)| pt)
.unwrap_or_else(|| lane.last_pt()), .unwrap_or_else(|| lane.last_pt()),
]) ])
.make_polygons_blindly(0.8 * LANE_THICKNESS); .make_polygons(0.8 * LANE_THICKNESS);
DrawBusStop { DrawBusStop {
id: stop.id, id: stop.id,
polygon, polygon,

View File

@ -36,14 +36,12 @@ impl DrawCar {
(false, false) (false, false)
}; };
let stopping_buffer = input let stopping_buffer = input.stopping_trace.map(|t| t.make_polygons(CAR_WIDTH));
.stopping_trace
.map(|t| t.make_polygons_blindly(CAR_WIDTH));
if input.body.length() < MIN_CAR_LENGTH { if input.body.length() < MIN_CAR_LENGTH {
return DrawCar { return DrawCar {
id: input.id, id: input.id,
body_polygon: input.body.make_polygons_blindly(CAR_WIDTH), body_polygon: input.body.make_polygons(CAR_WIDTH),
window_polygons: Vec::new(), window_polygons: Vec::new(),
left_blinkers: None, left_blinkers: None,
right_blinkers: None, right_blinkers: None,
@ -88,7 +86,7 @@ impl DrawCar {
DrawCar { DrawCar {
id: input.id, id: input.id,
body_polygon: input.body.make_polygons_blindly(CAR_WIDTH), body_polygon: input.body.make_polygons(CAR_WIDTH),
window_polygons: vec![front_window, back_window], window_polygons: vec![front_window, back_window],
left_blinkers: Some(( left_blinkers: Some((
Circle::new( Circle::new(
@ -209,5 +207,5 @@ impl Renderable for DrawCar {
fn thick_line_from_angle(thickness: f64, line_length: f64, pt: Pt2D, angle: Angle) -> Polygon { fn thick_line_from_angle(thickness: f64, line_length: f64, pt: Pt2D, angle: Angle) -> Polygon {
let pt2 = pt.project_away(line_length, angle); let pt2 = pt.project_away(line_length, angle);
// Shouldn't ever fail for a single line // Shouldn't ever fail for a single line
PolyLine::new(vec![pt, pt2]).make_polygons_blindly(thickness) PolyLine::new(vec![pt, pt2]).make_polygons(thickness)
} }

View File

@ -62,20 +62,12 @@ impl DrawExtraShape {
let road = closest let road = closest
.closest_pt(pl.middle(), 5.0 * LANE_THICKNESS * si::M) .closest_pt(pl.middle(), 5.0 * LANE_THICKNESS * si::M)
.map(|(r, _)| r); .map(|(r, _)| r);
if let Some(p) = pl.make_polygons(width) { Some(DrawExtraShape {
Some(DrawExtraShape { id,
id, shape: Shape::Polygon(pl.make_polygons(width)),
shape: Shape::Polygon(p), attributes: s.attributes,
attributes: s.attributes, road,
road, })
})
} else {
warn!(
"Discarding ExtraShape because its geometry was broken: {:?}",
s.attributes
);
None
}
} }
} }

View File

@ -26,7 +26,7 @@ pub struct DrawLane {
impl DrawLane { impl DrawLane {
pub fn new(lane: &Lane, map: &Map) -> DrawLane { pub fn new(lane: &Lane, map: &Map) -> DrawLane {
let road = map.get_r(lane.parent); let road = map.get_r(lane.parent);
let polygon = lane.lane_center_pts.make_polygons_blindly(LANE_THICKNESS); let polygon = lane.lane_center_pts.make_polygons(LANE_THICKNESS);
let mut markings: Vec<Marking> = Vec::new(); let mut markings: Vec<Marking> = Vec::new();
if road.is_canonical_lane(lane.id) { if road.is_canonical_lane(lane.id) {
@ -105,9 +105,6 @@ impl Renderable for DrawLane {
let color = opts.color.unwrap_or_else(|| { let color = opts.color.unwrap_or_else(|| {
let l = ctx.map.get_l(self.id); let l = ctx.map.get_l(self.id);
match l.lane_type { match l.lane_type {
_ if l.probably_broken => {
ctx.cs.get_def("broken lane", Color::rgb_f(1.0, 0.0, 0.565))
}
LaneType::Driving => ctx.cs.get_def("driving lane", Color::BLACK), LaneType::Driving => ctx.cs.get_def("driving lane", Color::BLACK),
LaneType::Bus => ctx.cs.get_def("bus lane", Color::rgb(190, 74, 76)), LaneType::Bus => ctx.cs.get_def("bus lane", Color::rgb(190, 74, 76)),
LaneType::Parking => ctx.cs.get_def("parking lane", Color::grey(0.2)), LaneType::Parking => ctx.cs.get_def("parking lane", Color::grey(0.2)),
@ -209,9 +206,7 @@ fn calculate_driving_lines(lane: &Lane, parent: &Road) -> Option<Marking> {
let dash_separation = 1.5 * si::M; let dash_separation = 1.5 * si::M;
let dash_len = 1.0 * si::M; let dash_len = 1.0 * si::M;
let lane_edge_pts = lane let lane_edge_pts = lane.lane_center_pts.shift_left(LANE_THICKNESS / 2.0);
.lane_center_pts
.shift_blindly_left(LANE_THICKNESS / 2.0);
if lane_edge_pts.length() < 2.0 * dash_separation { if lane_edge_pts.length() < 2.0 * dash_separation {
return None; return None;
} }
@ -293,7 +288,7 @@ fn turn_markings(turn: &Turn, map: &Map) -> Option<Marking> {
.lane_center_pts .lane_center_pts
.slice(len - 7.0 * si::M, len - 5.0 * si::M) .slice(len - 7.0 * si::M, len - 5.0 * si::M)
.0; .0;
let base_polygon = common_base.make_polygons_blindly(0.1); let base_polygon = common_base.make_polygons(0.1);
let turn_line = Line::new( let turn_line = Line::new(
common_base.last_pt(), common_base.last_pt(),
common_base common_base

View File

@ -81,14 +81,8 @@ impl DrawMap {
let mut closest: FindClosest<(RoadID, bool)> = let mut closest: FindClosest<(RoadID, bool)> =
map_model::FindClosest::new(&map.get_bounds()); map_model::FindClosest::new(&map.get_bounds());
for r in map.all_roads().iter() { for r in map.all_roads().iter() {
closest.add( closest.add((r.id, true), &r.center_pts.shift_right(LANE_THICKNESS));
(r.id, true), closest.add((r.id, false), &r.center_pts.shift_left(LANE_THICKNESS));
&r.center_pts.shift_blindly_right(LANE_THICKNESS),
);
closest.add(
(r.id, false),
&r.center_pts.shift_blindly_left(LANE_THICKNESS),
);
} }
let gps_bounds = map.get_gps_bounds(); let gps_bounds = map.get_gps_bounds();

View File

@ -37,7 +37,7 @@ impl DrawParcel {
DrawParcel { DrawParcel {
id: p.id, id: p.id,
boundary_polygon: PolyLine::new(p.points.clone()) boundary_polygon: PolyLine::new(p.points.clone())
.make_polygons_blindly(PARCEL_BOUNDARY_THICKNESS), .make_polygons(PARCEL_BOUNDARY_THICKNESS),
fill_polygon: Polygon::new(&p.points), fill_polygon: Polygon::new(&p.points),
} }
} }

View File

@ -44,7 +44,7 @@ impl DrawTurn {
// TODO This is hiding a real problem... some composite turns probably need to have their // TODO This is hiding a real problem... some composite turns probably need to have their
// geometry simplified a bit. // geometry simplified a bit.
if let Some(pl) = t.geom.without_last_line() { if let Some(pl) = t.geom.without_last_line() {
g.draw_polygon(color, &pl.make_polygons_blindly(2.0 * BIG_ARROW_THICKNESS)); g.draw_polygon(color, &pl.make_polygons(2.0 * BIG_ARROW_THICKNESS));
} }
// And a cap on the arrow // And a cap on the arrow
g.draw_arrow(color, BIG_ARROW_THICKNESS, &t.geom.last_line()); g.draw_arrow(color, BIG_ARROW_THICKNESS, &t.geom.last_line());

View File

@ -77,7 +77,7 @@ impl<'a> GfxCtx<'a> {
// Use graphics::Line internally for now, but make it easy to switch to something else by // Use graphics::Line internally for now, but make it easy to switch to something else by
// picking this API now. // picking this API now.
pub fn draw_line(&mut self, color: Color, thickness: f64, line: &geom::Line) { pub fn draw_line(&mut self, color: Color, thickness: f64, line: &geom::Line) {
self.draw_polygon(color, &line.to_polyline().make_polygons_blindly(thickness)); self.draw_polygon(color, &line.to_polyline().make_polygons(thickness));
} }
pub fn draw_rounded_line(&mut self, color: Color, thickness: f64, line: &geom::Line) { pub fn draw_rounded_line(&mut self, color: Color, thickness: f64, line: &geom::Line) {

View File

@ -22,8 +22,6 @@ impl PolyLine {
PolyLine { pts, length } PolyLine { pts, length }
} }
// TODO copy or mut?
// TODO this is likely not needed if we just have a way to shift in the other direction
pub fn reversed(&self) -> PolyLine { pub fn reversed(&self) -> PolyLine {
let mut pts = self.pts.clone(); let mut pts = self.pts.clone();
pts.reverse(); pts.reverse();
@ -152,86 +150,24 @@ impl PolyLine {
Some(PolyLine::new(self.pts[0..self.pts.len() - 1].to_vec())) Some(PolyLine::new(self.pts[0..self.pts.len() - 1].to_vec()))
} }
// Doesn't check if the result is valid // Things to remember about shifting polylines:
pub fn shift_blindly_right(&self, width: f64) -> PolyLine { // - the length before and after probably don't match up
// TODO Grrr, the new algorithm actually breaks pretty badly on medium. Disable it for now. // - the number of points does match
self.shift_blindly_with_sharp_angles(width) pub fn shift_right(&self, width: f64) -> PolyLine {
let mut result = self.shift_with_sharp_angles(width);
/*if self.pts.len() == 2 {
let l = Line::new(self.pts[0], self.pts[1]).shift_right(width);
return l.to_polyline();
}
let mut result: Vec<Pt2D> = Vec::new();
let mut pt3_idx = 2;
let mut pt1_raw = self.pts[0];
let mut pt2_raw = self.pts[1];
loop {
let pt3_raw = self.pts[pt3_idx];
let l1 = Line::new(pt1_raw, pt2_raw).shift_right(width);
let l2 = Line::new(pt2_raw, pt3_raw).shift_right(width);
// When the lines are perfectly parallel, it means pt2_shift_1st == pt2_shift_2nd and the
// original geometry is redundant.
let pt2_shift = line_intersection(&l1, &l2).unwrap_or_else(|| l1.pt2());
if pt3_idx == 2 {
result.push(l1.pt1());
}
// If the two line SEGMENTS intersected, then just use that one point.
if l1.intersects(&l2) {
result.push(pt2_shift);
} else {
// Otherwise, the line intersection will occur farther than width away from the
// original pt2_raw. At various angles, this explodes out way too much. So insert a
// few points to make the corner nicer.
result.push(l1.pt2());
result.push(Line::new(pt2_raw, pt2_shift).dist_along(width * si::M));
result.push(l2.pt1());
}
if pt3_idx == self.pts.len() - 1 {
result.push(l2.pt2());
break;
}
pt1_raw = pt2_raw;
pt2_raw = pt3_raw;
pt3_idx += 1;
}
// Might have extra points to handle sharp bends
assert!(result.len() >= self.pts.len());
PolyLine::new(result)*/
}
pub fn shift_blindly_left(&self, width: f64) -> PolyLine {
self.shift_blindly_with_sharp_angles(-width)
}
// Shifting might fail if the requested width doesn't fit in tight angles between points in the
// polyline.
// Things to remember about shifting polylines: the length before and after probably don't
// match up.
pub fn shift_right(&self, width: f64) -> Option<PolyLine> {
let mut result = self.shift_blindly_right(width);
fix_angles(self, &mut result); fix_angles(self, &mut result);
check_angles(self, &result); check_angles(self, &result);
Some(result) result
} }
pub fn shift_left(&self, width: f64) -> Option<PolyLine> { pub fn shift_left(&self, width: f64) -> PolyLine {
let mut result = self.shift_blindly_left(width); let mut result = self.shift_with_sharp_angles(-width);
fix_angles(self, &mut result); fix_angles(self, &mut result);
check_angles(self, &result); check_angles(self, &result);
Some(result) result
} }
// Doesn't massage sharp twists into more points. For polygon rendering. fn shift_with_sharp_angles(&self, width: f64) -> PolyLine {
fn shift_blindly_with_sharp_angles(&self, width: f64) -> PolyLine {
if self.pts.len() == 2 { if self.pts.len() == 2 {
let l = Line::new(self.pts[0], self.pts[1]).shift_either_direction(width); let l = Line::new(self.pts[0], self.pts[1]).shift_either_direction(width);
return l.to_polyline(); return l.to_polyline();
@ -270,45 +206,11 @@ impl PolyLine {
PolyLine::new(result) PolyLine::new(result)
} }
// Doesn't massage sharp twists into more points. For polygon rendering. Shifting might fail if pub fn make_polygons(&self, width: f64) -> Polygon {
// the requested width doesn't fit in tight angles between points in the polyline. // TODO Don't use the angle corrections yet -- they seem to do weird things.
fn shift_with_sharp_angles(&self, width: f64) -> Option<PolyLine> { let side1 = self.shift_with_sharp_angles(width / 2.0);
let result = if width >= 0.0 { let side2 = self.shift_with_sharp_angles(-width / 2.0);
self.shift_blindly_right(width)
} else {
self.shift_blindly_left(width)
};
// Check that the angles roughly match up between the original and shifted line
for (orig_l, shifted_l) in self.lines().iter().zip(result.lines().iter()) {
let orig_angle = orig_l.angle().normalized_degrees();
let shifted_angle = shifted_l.angle().normalized_degrees();
let delta = (shifted_angle - orig_angle).abs();
if delta > 0.00001 {
/*println!(
"Points changed angles from {} to {}",
orig_angle, shifted_angle
);*/
return None;
}
}
Some(result)
}
// This could fail by needing too much width for sharp angles
pub fn make_polygons(&self, width: f64) -> Option<Polygon> {
let side1 = self.shift_with_sharp_angles(width / 2.0)?;
let side2 = self.shift_with_sharp_angles(-width / 2.0)?;
Some(self.polygons_from_sides(&side1, &side2))
}
pub fn make_polygons_blindly(&self, width: f64) -> Polygon {
let side1 = self.shift_blindly_with_sharp_angles(width / 2.0);
let side2 = self.shift_blindly_with_sharp_angles(-width / 2.0);
self.polygons_from_sides(&side1, &side2)
}
fn polygons_from_sides(&self, side1: &PolyLine, side2: &PolyLine) -> Polygon {
let mut poly = Polygon { let mut poly = Polygon {
triangles: Vec::new(), triangles: Vec::new(),
}; };
@ -344,11 +246,7 @@ impl PolyLine {
break; break;
} }
polygons.push( polygons.push(self.slice(start, start + dash_len).0.make_polygons(width));
self.slice(start, start + dash_len)
.0
.make_polygons_blindly(width),
);
start += dash_len + dash_separation; start += dash_len + dash_separation;
} }
@ -442,18 +340,6 @@ impl fmt::Display for PolyLine {
} }
} }
// TODO unsure why this doesn't work. maybe see if mouse is inside polygon to check it out?
/*fn polygon_for_polyline(center_pts: &Vec<(f64, f64)>, width: f64) -> Vec<[f64; 2]> {
let mut result = shift_polyline(width / 2.0, center_pts);
let mut reversed_center_pts = center_pts.clone();
reversed_center_pts.reverse();
result.extend(shift_polyline(width / 2.0, &reversed_center_pts));
// TODO unclear if piston needs last point to match the first or not
let first_pt = result[0];
result.push(first_pt);
result.iter().map(|pair| [pair.0, pair.1]).collect()
}*/
fn fix_angles(orig: &PolyLine, result: &mut PolyLine) { fn fix_angles(orig: &PolyLine, result: &mut PolyLine) {
// Check that the angles roughly match up between the original and shifted line // Check that the angles roughly match up between the original and shifted line
for (idx, (orig_l, shifted_l)) in orig.lines().iter().zip(result.lines().iter()).enumerate() { for (idx, (orig_l, shifted_l)) in orig.lines().iter().zip(result.lines().iter()).enumerate() {

View File

@ -77,7 +77,7 @@ impl DrawRoad {
id: r.id, id: r.id,
polygon: r polygon: r
.center_pts .center_pts
.make_polygons_blindly(LANE_THICKNESS * (num_lanes as f64)), .make_polygons(LANE_THICKNESS * (num_lanes as f64)),
} }
} }

View File

@ -42,6 +42,6 @@ impl Area {
if self.points[0] == *self.points.last().unwrap() { if self.points[0] == *self.points.last().unwrap() {
return Polygon::new(&self.points); return Polygon::new(&self.points);
} }
PolyLine::new(self.points.clone()).make_polygons_blindly(LANE_THICKNESS) PolyLine::new(self.points.clone()).make_polygons(LANE_THICKNESS)
} }
} }

View File

@ -41,10 +41,6 @@ pub struct Lane {
pub lane_type: LaneType, pub lane_type: LaneType,
pub lane_center_pts: PolyLine, pub lane_center_pts: PolyLine,
// Remember that lane_center_pts and derived geometry is probably broken. Might be better to
// use this breakage to infer that a road doesn't have so many lanes.
pub probably_broken: bool,
pub src_i: IntersectionID, pub src_i: IntersectionID,
pub dst_i: IntersectionID, pub dst_i: IntersectionID,

View File

@ -97,7 +97,6 @@ pub fn make_half_map(
id, id,
// Temporary dummy value; this'll be calculated a bit later. // Temporary dummy value; this'll be calculated a bit later.
lane_center_pts: road_center_pts.clone(), lane_center_pts: road_center_pts.clone(),
probably_broken: false,
src_i, src_i,
dst_i, dst_i,
lane_type: lane.lane_type, lane_type: lane.lane_type,
@ -151,13 +150,7 @@ pub fn make_half_map(
// TODO need to factor in yellow center lines (but what's the right thing to even do? // 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 // Reverse points for British-style driving on the left
let width = LANE_THICKNESS * (0.5 + (offset as f64)); let width = LANE_THICKNESS * (0.5 + (offset as f64));
let (lane_center_pts, probably_broken) = match unshifted_pts.shift_right(width) { l.lane_center_pts = unshifted_pts.shift_right(width);
Some(pts) => (pts, false),
// TODO wasteful to calculate again, but eh
None => (unshifted_pts.shift_blindly_right(width), true),
};
l.lane_center_pts = lane_center_pts;
l.probably_broken = probably_broken;
} }
for i in m.intersections.iter_mut() { for i in m.intersections.iter_mut() {

View File

@ -33,8 +33,8 @@ pub fn intersection_polygon(i: &Intersection, roads: &mut Vec<Road>) -> Vec<Pt2D
panic!("Incident road {} doesn't have an endpoint at {}", id, i.id); panic!("Incident road {} doesn't have an endpoint at {}", id, i.id);
}; };
let pl_normal = line.shift_right(width_normal).unwrap(); let pl_normal = line.shift_right(width_normal);
let pl_reverse = line.shift_left(width_reverse).unwrap(); let pl_reverse = line.shift_left(width_reverse);
(*id, line.last_line().angle(), pl_normal, pl_reverse) (*id, line.last_line().angle(), pl_normal, pl_reverse)
}) })
.collect(); .collect();
@ -134,13 +134,11 @@ fn degenerate_twoway(
endpoints.push( endpoints.push(
r.center_pts r.center_pts
.shift_left(LANE_THICKNESS * (r.children_backwards.len() as f64)) .shift_left(LANE_THICKNESS * (r.children_backwards.len() as f64))
.unwrap()
.first_pt(), .first_pt(),
); );
endpoints.push( endpoints.push(
r.center_pts r.center_pts
.shift_right(LANE_THICKNESS * (r.children_forwards.len() as f64)) .shift_right(LANE_THICKNESS * (r.children_forwards.len() as f64))
.unwrap()
.first_pt(), .first_pt(),
); );
} else { } else {
@ -154,13 +152,11 @@ fn degenerate_twoway(
endpoints.push( endpoints.push(
r.center_pts r.center_pts
.shift_right(LANE_THICKNESS * (r.children_forwards.len() as f64)) .shift_right(LANE_THICKNESS * (r.children_forwards.len() as f64))
.unwrap()
.last_pt(), .last_pt(),
); );
endpoints.push( endpoints.push(
r.center_pts r.center_pts
.shift_left(LANE_THICKNESS * (r.children_backwards.len() as f64)) .shift_left(LANE_THICKNESS * (r.children_backwards.len() as f64))
.unwrap()
.last_pt(), .last_pt(),
); );
} }
@ -283,8 +279,8 @@ fn make_new_polygon(
r.center_pts = shorter_center.clone(); r.center_pts = shorter_center.clone();
(fwd_width, back_width) (fwd_width, back_width)
}; };
let pl_normal = shorter_center.shift_right(width_normal).unwrap(); let pl_normal = shorter_center.shift_right(width_normal);
let pl_reverse = shorter_center.shift_left(width_reverse).unwrap(); let pl_reverse = shorter_center.shift_left(width_reverse);
// Toss in the original corners, so the intersection polygon doesn't cover area not // Toss in the original corners, so the intersection polygon doesn't cover area not
// originally covered by the thick road bands. // originally covered by the thick road bands.

View File

@ -34,14 +34,14 @@ pub fn run(g: &mut GfxCtx) {
(north_yellow, RelatedColors::new(0.0, 1.0, 0.0)), (north_yellow, RelatedColors::new(0.0, 1.0, 0.0)),
(south_yellow, RelatedColors::new(0.0, 0.0, 1.0)), (south_yellow, RelatedColors::new(0.0, 0.0, 1.0)),
] { ] {
let lane1_in = yellow_line.shift_right(shift1_width).unwrap(); let lane1_in = yellow_line.shift_right(shift1_width);
draw_lane(g, &lane1_in, colors.next().unwrap()); draw_lane(g, &lane1_in, colors.next().unwrap());
let lane2_in = yellow_line.shift_right(shift2_width).unwrap(); let lane2_in = yellow_line.shift_right(shift2_width);
draw_lane(g, &lane2_in, colors.next().unwrap()); draw_lane(g, &lane2_in, colors.next().unwrap());
let lane1_out = yellow_line.reversed().shift_right(shift1_width).unwrap(); let lane1_out = yellow_line.reversed().shift_right(shift1_width);
draw_lane(g, &lane1_out, colors.next().unwrap()); draw_lane(g, &lane1_out, colors.next().unwrap());
let lane2_out = yellow_line.reversed().shift_right(shift2_width).unwrap(); let lane2_out = yellow_line.reversed().shift_right(shift2_width);
draw_lane(g, &lane2_out, colors.next().unwrap()); draw_lane(g, &lane2_out, colors.next().unwrap());
draw_polyline(g, &yellow_line, thin, YELLOW); draw_polyline(g, &yellow_line, thin, YELLOW);
@ -77,7 +77,7 @@ impl Iterator for RelatedColors {
} }
pub fn draw_lane(g: &mut GfxCtx, pl: &PolyLine, color: Color) { pub fn draw_lane(g: &mut GfxCtx, pl: &PolyLine, color: Color) {
g.draw_polygon(color, &pl.make_polygons(LANE_THICKNESS).unwrap()); g.draw_polygon(color, &pl.make_polygons(LANE_THICKNESS));
// Debug the center points // Debug the center points
draw_polyline(g, pl, 0.25, SOLID_BLACK); draw_polyline(g, pl, 0.25, SOLID_BLACK);

View File

@ -28,26 +28,18 @@ pub fn run(g: &mut GfxCtx, labels: &mut Vec<(Pt2D, String)>) {
labels.push((*pt, format!("p{}", idx + 1))); labels.push((*pt, format!("p{}", idx + 1)));
} }
if let Some(poly) = center_pts.make_polygons(width) { g.draw_polygon(BLACK, &center_pts.make_polygons(width));
g.draw_polygon(BLACK, &poly);
}
// TODO colored labels! // TODO colored labels!
if let Some(side1) = center_pts.shift_right(width / 2.0) { let side1 = center_pts.shift_right(width / 2.0);
//draw_polyline(g, &side1, thin, BLUE); //draw_polyline(g, &side1, thin, BLUE);
for (idx, pt) in side1.points().iter().enumerate() { for (idx, pt) in side1.points().iter().enumerate() {
labels.push((*pt, format!("L{}", idx + 1))); labels.push((*pt, format!("L{}", idx + 1)));
}
} else {
println!("side1 borked");
} }
if let Some(side2) = center_pts.shift_left(width / 2.0) { let side2 = center_pts.shift_left(width / 2.0);
//draw_polyline(g, &side2, thin, GREEN); //draw_polyline(g, &side2, thin, GREEN);
for (idx, pt) in side2.points().iter().enumerate() { for (idx, pt) in side2.points().iter().enumerate() {
labels.push((*pt, format!("R{}", idx + 1))); labels.push((*pt, format!("R{}", idx + 1)));
}
} else {
println!("side2 borked");
} }
} }

View File

@ -34,36 +34,25 @@ pub fn run(p3_offset: (f64, f64), g: &mut GfxCtx, labels: &mut Vec<(Pt2D, String
draw_polyline(g, &pts, thick, RED); draw_polyline(g, &pts, thick, RED);
if let Some(poly) = pts.make_polygons(shift_away) { g.draw_polygon(BLACK, &pts.make_polygons(shift_away));
g.draw_polygon(BLACK, &poly);
}
// Two lanes on one side of the road // Two lanes on one side of the road
if let Some(l1_pts) = pts.shift_right(shift_away) { let l1_pts = pts.shift_right(shift_away);
for (idx, pt) in l1_pts.points().iter().enumerate() { for (idx, pt) in l1_pts.points().iter().enumerate() {
labels.push((*pt, format!("l1_p{}", idx + 1))); labels.push((*pt, format!("l1_p{}", idx + 1)));
}
draw_polyline(g, &l1_pts, thin, GREEN);
} else {
println!("l1_pts borked");
} }
draw_polyline(g, &l1_pts, thin, GREEN);
if let Some(l2_pts) = pts.shift_right(shift_away * 2.0) { let l2_pts = pts.shift_right(shift_away * 2.0);
for (idx, pt) in l2_pts.points().iter().enumerate() { for (idx, pt) in l2_pts.points().iter().enumerate() {
labels.push((*pt, format!("l2_p{}", idx + 1))); labels.push((*pt, format!("l2_p{}", idx + 1)));
}
draw_polyline(g, &l2_pts, thin, GREEN);
} else {
println!("l2_pts borked");
} }
draw_polyline(g, &l2_pts, thin, GREEN);
// Other side // Other side
if let Some(l3_pts) = pts.reversed().shift_right(shift_away) { let l3_pts = pts.reversed().shift_right(shift_away);
for (idx, pt) in l3_pts.points().iter().enumerate() { for (idx, pt) in l3_pts.points().iter().enumerate() {
labels.push((*pt, format!("l3_p{}", idx + 1))); labels.push((*pt, format!("l3_p{}", idx + 1)));
}
draw_polyline(g, &l3_pts, thin, BLUE);
} else {
println!("l3_pts borked");
} }
draw_polyline(g, &l3_pts, thin, BLUE);
} }

View File

@ -864,7 +864,7 @@ impl DrivingSimState {
1.0 - progress 1.0 - progress
}; };
// TODO we're assuming the parking lane is to the right of us! // TODO we're assuming the parking lane is to the right of us!
base_body.shift_blindly_right(project_away_ratio * LANE_THICKNESS) base_body.shift_right(project_away_ratio * LANE_THICKNESS)
} else { } else {
base_body base_body
}; };

View File

@ -71,12 +71,10 @@ impl Road {
]); ]);
if direction { if direction {
let width = LANE_THICKNESS * (self.lanes.fwd.len() as f64); let width = LANE_THICKNESS * (self.lanes.fwd.len() as f64);
pl.shift_blindly_right(width / 2.0) pl.shift_right(width / 2.0).make_polygons(width)
.make_polygons_blindly(width)
} else { } else {
let width = LANE_THICKNESS * (self.lanes.back.len() as f64); let width = LANE_THICKNESS * (self.lanes.back.len() as f64);
pl.shift_blindly_left(width / 2.0) pl.shift_left(width / 2.0).make_polygons(width)
.make_polygons_blindly(width)
} }
} }
@ -95,8 +93,8 @@ impl Road {
for (idx, lt) in self.lanes.fwd.iter().enumerate() { for (idx, lt) in self.lanes.fwd.iter().enumerate() {
let polygon = base let polygon = base
.shift_blindly_right(((idx as f64) + 0.5) * LANE_THICKNESS) .shift_right(((idx as f64) + 0.5) * LANE_THICKNESS)
.make_polygons_blindly(LANE_THICKNESS); .make_polygons(LANE_THICKNESS);
g.draw_polygon( g.draw_polygon(
if highlight_fwd { if highlight_fwd {
HIGHLIGHT_COLOR HIGHLIGHT_COLOR
@ -108,8 +106,8 @@ impl Road {
} }
for (idx, lt) in self.lanes.back.iter().enumerate() { for (idx, lt) in self.lanes.back.iter().enumerate() {
let polygon = base let polygon = base
.shift_blindly_left(((idx as f64) + 0.5) * LANE_THICKNESS) .shift_left(((idx as f64) + 0.5) * LANE_THICKNESS)
.make_polygons_blindly(LANE_THICKNESS); .make_polygons(LANE_THICKNESS);
g.draw_polygon( g.draw_polygon(
if highlight_back { if highlight_back {
HIGHLIGHT_COLOR HIGHLIGHT_COLOR
@ -120,10 +118,7 @@ impl Road {
); );
} }
g.draw_polygon( g.draw_polygon(Color::YELLOW, &base.make_polygons(CENTER_LINE_THICKNESS));
Color::YELLOW,
&base.make_polygons_blindly(CENTER_LINE_THICKNESS),
);
if let Some(ref label) = self.fwd_label { if let Some(ref label) = self.fwd_label {
canvas.draw_text_at( canvas.draw_text_at(

View File

@ -49,7 +49,7 @@ pub fn run(t: &mut TestRunner) {
assert_eq!( assert_eq!(
PolyLine::new(vec![pt1, pt2, pt3, pt4, pt5]).shift_right(width), PolyLine::new(vec![pt1, pt2, pt3, pt4, pt5]).shift_right(width),
Some(PolyLine::new(vec![pt1_s, pt2_s, pt3_s, pt4_s, pt5_s])) PolyLine::new(vec![pt1_s, pt2_s, pt3_s, pt4_s, pt5_s])
); );
}), }),
); );
@ -66,7 +66,7 @@ pub fn run(t: &mut TestRunner) {
assert_eq!( assert_eq!(
PolyLine::new(vec![pt1, pt2]).shift_right(width), PolyLine::new(vec![pt1, pt2]).shift_right(width),
Some(l.to_polyline()) l.to_polyline()
); );
}), }),
); );