Remove the weird shifting/angle inversions from DrivingSide. First step

of #311. Tested to not break righthand maps.
This commit is contained in:
Dustin Carlino 2020-09-03 19:43:30 -07:00
parent 9be79f6e2d
commit f610c66572
14 changed files with 90 additions and 232 deletions

View File

@ -60,17 +60,11 @@ fn use_parking_hints(map: &mut RawMap, path: String, timer: &mut Timer) {
let center = PolyLine::must_new(r.center_points.clone());
closest.add(
(*id, true),
map.config
.driving_side
.must_right_shift(center.clone(), DIRECTED_ROAD_THICKNESS)
.points(),
center.must_shift_right(DIRECTED_ROAD_THICKNESS).points(),
);
closest.add(
(*id, false),
map.config
.driving_side
.must_left_shift(center, DIRECTED_ROAD_THICKNESS)
.points(),
center.must_shift_left(DIRECTED_ROAD_THICKNESS).points(),
);
}

View File

@ -417,12 +417,14 @@ impl ChangeWay {
let r = map.get_r(*id);
batch.push(
Color::GREEN,
map.must_right_shift(r.center_pts.clone(), r.get_half_width(map))
r.center_pts
.must_shift_right(r.get_half_width(map))
.make_polygons(thickness),
);
batch.push(
Color::BLUE,
map.must_left_shift(r.center_pts.clone(), r.get_half_width(map))
r.center_pts
.must_shift_left(r.get_half_width(map))
.make_polygons(thickness),
);
}

View File

@ -101,13 +101,11 @@ impl DrawIntersection {
// TODO warn
return None;
}
let last_line = map.right_shift_line(
rightmost
.lane_center_pts
.exact_slice(Distance::ZERO, rightmost.length() - trim_back)
.last_line(),
rightmost.width,
);
let last_line = rightmost
.lane_center_pts
.exact_slice(Distance::ZERO, rightmost.length() - trim_back)
.last_line()
.shift_right(rightmost.width);
let octagon = make_octagon(last_line.pt2(), Distance::meters(1.0), last_line.angle());
let pole = Line::must_new(
@ -214,20 +212,18 @@ pub fn calculate_corners(i: &Intersection, map: &Map) -> Vec<Polygon> {
let l2 = map.get_l(turn.id.dst);
if let Some(poly) = (|| {
let mut pts = map
.left_shift(turn.geom.clone(), width / 2.0)
.ok()?
.into_points();
pts.push(map.left_shift_line(l2.first_line(), width / 2.0).pt1());
pts.push(map.right_shift_line(l2.first_line(), width / 2.0).pt1());
let mut pts = turn.geom.shift_left(width / 2.0).ok()?.into_points();
pts.push(l2.first_line().shift_left(width / 2.0).pt1());
pts.push(l2.first_line().shift_right(width / 2.0).pt1());
pts.extend(
map.right_shift(turn.geom.clone(), width / 2.0)
turn.geom
.shift_right(width / 2.0)
.ok()?
.reversed()
.into_points(),
);
pts.push(map.right_shift_line(l1.last_line(), width / 2.0).pt2());
pts.push(map.left_shift_line(l1.last_line(), width / 2.0).pt2());
pts.push(l1.last_line().shift_right(width / 2.0).pt2());
pts.push(l1.last_line().shift_left(width / 2.0).pt2());
pts.push(pts[0]);
Some(Polygon::buggy_new(pts))
})() {
@ -259,15 +255,11 @@ fn calculate_border_arrows(i: &Intersection, r: &Road, map: &Map) -> Vec<Polygon
if !i.outgoing_lanes.is_empty() {
let (line, width) = if r.dst_i == i.id {
(
map.left_shift_line(center.last_line(), width_back / 2.0)
.reverse(),
center.last_line().shift_left(width_back / 2.0).reverse(),
width_back,
)
} else {
(
map.right_shift_line(center.first_line(), width_fwd / 2.0),
width_fwd,
)
(center.first_line().shift_right(width_fwd / 2.0), width_fwd)
};
result.push(
// DEGENERATE_INTERSECTION_HALF_LENGTH is 2.5m...
@ -283,15 +275,11 @@ fn calculate_border_arrows(i: &Intersection, r: &Road, map: &Map) -> Vec<Polygon
if !i.incoming_lanes.is_empty() {
let (line, width) = if r.dst_i == i.id {
(
map.right_shift_line(center.last_line(), width_fwd / 2.0)
.reverse(),
center.last_line().shift_right(width_fwd / 2.0).reverse(),
width_fwd,
)
} else {
(
map.left_shift_line(center.first_line(), width_back / 2.0),
width_back,
)
(center.first_line().shift_left(width_back / 2.0), width_back)
};
result.push(
PolyLine::must_new(vec![

View File

@ -58,15 +58,12 @@ impl DrawLane {
}
LaneType::Shoulder => {}
LaneType::Parking => {
draw.extend(
app.cs.general_road_marking,
calculate_parking_lines(map, lane),
);
draw.extend(app.cs.general_road_marking, calculate_parking_lines(lane));
}
LaneType::Driving | LaneType::Bus => {
draw.extend(
app.cs.general_road_marking,
calculate_driving_lines(map, lane, road),
calculate_driving_lines(lane, road),
);
draw.extend(
app.cs.general_road_marking,
@ -249,7 +246,7 @@ fn calculate_sidewalk_lines(lane: &Lane) -> Vec<Polygon> {
result
}
fn calculate_parking_lines(map: &Map, lane: &Lane) -> Vec<Polygon> {
fn calculate_parking_lines(lane: &Lane) -> Vec<Polygon> {
// meters, but the dims get annoying below to remove
let leg_length = Distance::meters(1.0);
@ -260,7 +257,7 @@ fn calculate_parking_lines(map: &Map, lane: &Lane) -> Vec<Polygon> {
let (pt, lane_angle) = lane
.lane_center_pts
.must_dist_along(PARKING_SPOT_LENGTH * (1.0 + idx as f64));
let perp_angle = map.driving_side_angle(lane_angle.rotate_degs(270.0));
let perp_angle = lane_angle.rotate_degs(270.0);
// Find the outside of the lane. Actually, shift inside a little bit, since the line
// will have thickness, but shouldn't really intersect the adjacent line
// when drawn.
@ -283,7 +280,7 @@ fn calculate_parking_lines(map: &Map, lane: &Lane) -> Vec<Polygon> {
// Because the stripe straddles two lanes, it'll be partly hidden on one side. There are a bunch of
// ways to work around this z-order issue. The current approach is to rely on the fact that
// quadtrees return LaneIDs in order, and lanes are always created from left->right.
fn calculate_driving_lines(map: &Map, lane: &Lane, parent: &Road) -> Vec<Polygon> {
fn calculate_driving_lines(lane: &Lane, parent: &Road) -> Vec<Polygon> {
let lanes = parent.lanes_ltr();
let idx = parent.offset(lane.id);
@ -294,9 +291,9 @@ fn calculate_driving_lines(map: &Map, lane: &Lane, parent: &Road) -> Vec<Polygon
}
let lane_edge_pts = if lanes[idx].1 == Direction::Fwd {
map.must_left_shift(lane.lane_center_pts.clone(), lane.width / 2.0)
lane.lane_center_pts.must_shift_left(lane.width / 2.0)
} else {
map.must_right_shift(lane.lane_center_pts.clone(), lane.width / 2.0)
lane.lane_center_pts.must_shift_right(lane.width / 2.0)
};
lane_edge_pts.dashed_lines(
Distance::meters(0.25),

View File

@ -206,9 +206,9 @@ impl DrawPedCrowd {
PedCrowdLocation::Sidewalk(on, contraflow) => {
let pl_slice = on.exact_slice(input.low, input.high, map);
if contraflow {
map.left_shift(pl_slice, SIDEWALK_THICKNESS / 4.0)
pl_slice.shift_left(SIDEWALK_THICKNESS / 4.0)
} else {
map.right_shift(pl_slice, SIDEWALK_THICKNESS / 4.0)
pl_slice.shift_right(SIDEWALK_THICKNESS / 4.0)
}
.unwrap_or_else(|_| on.exact_slice(input.low, input.high, map))
}

View File

@ -1,6 +1,6 @@
use crate::make::initial::{Intersection, Road};
use crate::osm;
use crate::raw::{DrivingSide, OriginalRoad};
use crate::raw::OriginalRoad;
use abstutil::{wraparound_get, Timer};
use geom::{Circle, Distance, Line, PolyLine, Polygon, Pt2D, Ring, EPSILON_DIST};
use std::collections::BTreeMap;
@ -11,7 +11,6 @@ const DEGENERATE_INTERSECTION_HALF_LENGTH: Distance = Distance::const_meters(2.5
// carves up part of that space, doesn't reach past it.
// Also returns a list of labeled polygons for debugging.
pub fn intersection_polygon(
driving_side: DrivingSide,
i: &Intersection,
roads: &mut BTreeMap<OriginalRoad, Road>,
timer: &mut Timer,
@ -35,8 +34,8 @@ pub fn intersection_polygon(
} else {
panic!("Incident road {} doesn't have an endpoint at {}", id, i.id);
};
let pl_normal = driving_side.right_shift(pl.clone(), r.half_width)?;
let pl_reverse = driving_side.left_shift(pl.clone(), r.half_width)?;
let pl_normal = pl.shift_right(r.half_width)?;
let pl_reverse = pl.shift_left(r.half_width)?;
lines.push((*id, pl.last_line(), pl_normal, pl_reverse));
}
@ -47,24 +46,23 @@ pub fn intersection_polygon(
});
if lines.len() == 1 {
return deadend(driving_side, roads, i.id, &lines);
return deadend(roads, i.id, &lines);
}
let rollback = lines
.iter()
.map(|(r, _, _, _)| (*r, roads[r].trimmed_center_pts.clone()))
.collect::<Vec<_>>();
if let Some(result) = on_off_ramp(driving_side, roads, i.id, lines.clone()) {
if let Some(result) = on_off_ramp(roads, i.id, lines.clone()) {
Ok(result)
} else {
for (r, trimmed_center_pts) in rollback {
roads.get_mut(&r).unwrap().trimmed_center_pts = trimmed_center_pts;
}
generalized_trim_back(driving_side, roads, i.id, &lines, timer)
generalized_trim_back(roads, i.id, &lines, timer)
}
}
fn generalized_trim_back(
driving_side: DrivingSide,
roads: &mut BTreeMap<OriginalRoad, Road>,
i: osm::NodeID,
lines: &Vec<(OriginalRoad, Line, PolyLine, PolyLine)>,
@ -221,27 +219,11 @@ 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(
driving_side
.right_shift(r.trimmed_center_pts.clone(), r.half_width)?
.last_pt(),
);
endpoints.push(
driving_side
.left_shift(r.trimmed_center_pts.clone(), r.half_width)?
.last_pt(),
);
endpoints.push(r.trimmed_center_pts.shift_right(r.half_width)?.last_pt());
endpoints.push(r.trimmed_center_pts.shift_left(r.half_width)?.last_pt());
} else {
endpoints.push(
driving_side
.left_shift(r.trimmed_center_pts.clone(), r.half_width)?
.first_pt(),
);
endpoints.push(
driving_side
.right_shift(r.trimmed_center_pts.clone(), r.half_width)?
.first_pt(),
);
endpoints.push(r.trimmed_center_pts.shift_left(r.half_width)?.first_pt());
endpoints.push(r.trimmed_center_pts.shift_right(r.half_width)?.first_pt());
}
if back_pl.length() >= EPSILON_DIST * 3.0 && adj_back_pl.length() >= EPSILON_DIST * 3.0 {
@ -291,7 +273,6 @@ fn generalized_trim_back(
}
fn deadend(
driving_side: DrivingSide,
roads: &mut BTreeMap<OriginalRoad, Road>,
i: osm::NodeID,
lines: &Vec<(OriginalRoad, Line, PolyLine, PolyLine)>,
@ -335,23 +316,11 @@ fn deadend(
// TODO Refactor with generalized_trim_back.
let mut endpts = vec![pl_b.last_pt(), pl_a.last_pt()];
if r.dst_i == i {
endpts.push(
driving_side
.right_shift(trimmed.clone(), r.half_width)?
.last_pt(),
);
endpts.push(
driving_side
.left_shift(trimmed.clone(), r.half_width)?
.last_pt(),
);
endpts.push(trimmed.shift_right(r.half_width)?.last_pt());
endpts.push(trimmed.shift_left(r.half_width)?.last_pt());
} else {
endpts.push(
driving_side
.left_shift(trimmed.clone(), r.half_width)?
.first_pt(),
);
endpts.push(driving_side.right_shift(trimmed, r.half_width)?.first_pt());
endpts.push(trimmed.shift_left(r.half_width)?.first_pt());
endpts.push(trimmed.shift_right(r.half_width)?.first_pt());
}
endpts.dedup();
@ -379,7 +348,6 @@ struct Piece {
// Try to apply to any 3-way. Might fail for many reasons.
fn on_off_ramp(
driving_side: DrivingSide,
roads: &mut BTreeMap<OriginalRoad, Road>,
i: osm::NodeID,
lines: Vec<(OriginalRoad, Line, PolyLine, PolyLine)>,
@ -556,27 +524,27 @@ fn on_off_ramp(
// Shift those final centers out again to find the main endpoints for the polygon.
if r.dst_i == i {
endpoints.push(
driving_side
.right_shift(r.trimmed_center_pts.clone(), r.half_width)
r.trimmed_center_pts
.shift_right(r.half_width)
.ok()?
.last_pt(),
);
endpoints.push(
driving_side
.left_shift(r.trimmed_center_pts.clone(), r.half_width)
r.trimmed_center_pts
.shift_left(r.half_width)
.ok()?
.last_pt(),
);
} else {
endpoints.push(
driving_side
.left_shift(r.trimmed_center_pts.clone(), r.half_width)
r.trimmed_center_pts
.shift_left(r.half_width)
.ok()?
.first_pt(),
);
endpoints.push(
driving_side
.right_shift(r.trimmed_center_pts.clone(), r.half_width)
r.trimmed_center_pts
.shift_right(r.half_width)
.ok()?
.first_pt(),
);

View File

@ -2,7 +2,7 @@ mod geometry;
pub mod lane_specs;
pub use self::geometry::intersection_polygon;
use crate::raw::{DrivingSide, OriginalRoad, RawMap, RawRoad};
use crate::raw::{OriginalRoad, RawMap, RawRoad};
use crate::{osm, IntersectionType};
use abstutil::{Tags, Timer};
use geom::{Bounds, Circle, Distance, PolyLine, Polygon, Pt2D};
@ -29,9 +29,9 @@ pub struct Road {
}
impl Road {
pub fn new(id: OriginalRoad, r: &RawRoad, driving_side: DrivingSide) -> Road {
pub fn new(id: OriginalRoad, r: &RawRoad) -> Road {
let lane_specs_ltr = lane_specs::get_lane_specs_ltr(&r.osm_tags);
let (trimmed_center_pts, total_width) = r.get_geometry(id, driving_side);
let (trimmed_center_pts, total_width) = r.get_geometry(id);
Road {
id,
@ -89,14 +89,13 @@ impl InitialMap {
m.intersections.get_mut(&id.i1).unwrap().roads.insert(*id);
m.intersections.get_mut(&id.i2).unwrap().roads.insert(*id);
m.roads
.insert(*id, Road::new(*id, r, raw.config.driving_side));
m.roads.insert(*id, Road::new(*id, r));
}
timer.start_iter("find each intersection polygon", m.intersections.len());
for i in m.intersections.values_mut() {
timer.next();
match intersection_polygon(raw.config.driving_side, i, &mut m.roads, timer) {
match intersection_polygon(i, &mut m.roads, timer) {
Ok((poly, _)) => {
i.polygon = poly;
}
@ -142,9 +141,7 @@ impl InitialMap {
.extend_to_length(min_len)
.reversed();
}
i.polygon = intersection_polygon(raw.config.driving_side, i, &mut m.roads, timer)
.unwrap()
.0;
i.polygon = intersection_polygon(i, &mut m.roads, timer).unwrap().0;
timer.note(format!(
"Shifted border {} out a bit to make the road a reasonable length",
i.id

View File

@ -138,8 +138,9 @@ impl Map {
}
// TODO Maybe easier to use the road's "yellow center line" and shift left/right from
// there.
let road_left_pts = map
.left_shift(road.center_pts.clone(), r.half_width)
let road_left_pts = road
.center_pts
.shift_left(r.half_width)
.unwrap_or_else(|_| road.center_pts.clone());
let mut width_so_far = Distance::ZERO;
@ -156,14 +157,13 @@ impl Map {
road.lanes_ltr.push((id, lane.dir, lane.lt));
let pl = if let Ok(pl) =
map.right_shift(road_left_pts.clone(), width_so_far + (lane.width / 2.0))
{
pl
} else {
timer.error(format!("{} geometry broken; lane not shifted!", id));
road_left_pts.clone()
};
let pl =
if let Ok(pl) = road_left_pts.shift_right(width_so_far + (lane.width / 2.0)) {
pl
} else {
timer.error(format!("{} geometry broken; lane not shifted!", id));
road_left_pts.clone()
};
let lane_center_pts = if lane.dir == Direction::Fwd {
pl
} else {

View File

@ -359,12 +359,8 @@ fn make_shared_sidewalk_corner(
// Find all of the points on the intersection polygon between the two sidewalks. Assumes
// sidewalks are the same length.
let corner1 = driving_side
.right_shift_line(l1.last_line(), l1.width / 2.0)
.pt2();
let corner2 = driving_side
.right_shift_line(l2.first_line(), l2.width / 2.0)
.pt1();
let corner1 = l1.last_line().shift_right(l1.width / 2.0).pt2();
let corner2 = l2.first_line().shift_right(l2.width / 2.0).pt1();
// TODO Something like this will be MUCH simpler and avoid going around the long way sometimes.
if false {
@ -393,8 +389,8 @@ fn make_shared_sidewalk_corner(
}
pts_between.extend(
driving_side
.must_right_shift(PolyLine::must_new(deduped), l1.width.min(l2.width) / 2.0)
PolyLine::must_new(deduped)
.must_shift_right(l1.width.min(l2.width) / 2.0)
.points(),
);
}

View File

@ -6,7 +6,7 @@ use crate::{
PathConstraints, PathRequest, Pathfinder, Position, Road, RoadID, Turn, TurnID, TurnType, Zone,
};
use abstutil::Timer;
use geom::{Angle, Bounds, Distance, GPSBounds, Line, PolyLine, Polygon, Pt2D, Ring, Time};
use geom::{Bounds, GPSBounds, Polygon, Pt2D, Ring, Time};
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, BTreeSet, HashSet, VecDeque};
@ -585,32 +585,6 @@ impl Map {
None
}
pub fn right_shift(&self, pl: PolyLine, width: Distance) -> Result<PolyLine, String> {
self.config.driving_side.right_shift(pl, width)
}
pub fn must_right_shift(&self, pl: PolyLine, width: Distance) -> PolyLine {
self.right_shift(pl, width).unwrap()
}
pub fn left_shift(&self, pl: PolyLine, width: Distance) -> Result<PolyLine, String> {
self.config.driving_side.left_shift(pl, width)
}
pub fn must_left_shift(&self, pl: PolyLine, width: Distance) -> PolyLine {
self.left_shift(pl, width).unwrap()
}
pub fn right_shift_line(&self, line: Line, width: Distance) -> Line {
self.config.driving_side.right_shift_line(line, width)
}
pub fn left_shift_line(&self, line: Line, width: Distance) -> Line {
self.config.driving_side.left_shift_line(line, width)
}
pub fn driving_side_angle(&self, a: Angle) -> Angle {
self.config.driving_side.angle_offset(a)
}
// Last resort
pub fn get_driving_side(&self) -> DrivingSide {
self.config.driving_side
}
// TODO Sort of a temporary hack
pub fn hack_override_offstreet_spots(&mut self, spots_per_bldg: usize) {
for b in &mut self.buildings {

View File

@ -297,7 +297,9 @@ impl Movement {
left = right;
}
let mut pl = map.must_right_shift(r.get_left_side(map), (leftmost + rightmost) / 2.0);
let mut pl = r
.get_left_side(map)
.must_shift_right((leftmost + rightmost) / 2.0);
if self.id.from.dir == Direction::Back {
pl = pl.reversed();
}

View File

@ -313,7 +313,9 @@ impl UberTurnGroup {
left = right;
}
let mut pl = map.must_right_shift(r.get_left_side(map), (leftmost + rightmost) / 2.0);
let mut pl = r
.get_left_side(map)
.must_shift_right((leftmost + rightmost) / 2.0);
// Point towards the intersection
if self.from.dir == Direction::Back {
pl = pl.reversed();

View File

@ -1,7 +1,7 @@
use crate::make::initial::lane_specs::get_lane_specs_ltr;
use crate::{osm, AreaType, Direction, IntersectionType, LaneType, MapConfig, NamePerLanguage};
use abstutil::{deserialize_btreemap, serialize_btreemap, Tags, Timer};
use geom::{Angle, Circle, Distance, GPSBounds, Line, PolyLine, Polygon, Pt2D};
use geom::{Circle, Distance, GPSBounds, PolyLine, Polygon, Pt2D};
use petgraph::graphmap::DiGraphMap;
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, BTreeSet};
@ -153,14 +153,10 @@ impl RawMap {
};
let mut roads = BTreeMap::new();
for r in &i.roads {
roads.insert(
*r,
initial::Road::new(*r, &self.roads[r], self.config.driving_side),
);
roads.insert(*r, initial::Road::new(*r, &self.roads[r]));
}
let (poly, debug) =
initial::intersection_polygon(self.config.driving_side, &i, &mut roads, timer).unwrap();
let (poly, debug) = initial::intersection_polygon(&i, &mut roads, timer).unwrap();
(
poly,
roads
@ -246,11 +242,7 @@ pub struct RawRoad {
impl RawRoad {
// Returns the corrected center and half width
pub fn get_geometry(
&self,
id: OriginalRoad,
driving_side: DrivingSide,
) -> (PolyLine, Distance) {
pub fn get_geometry(&self, id: OriginalRoad) -> (PolyLine, Distance) {
let lane_specs = get_lane_specs_ltr(&self.osm_tags);
let mut total_width = Distance::ZERO;
let mut sidewalk_right = None;
@ -270,10 +262,10 @@ impl RawRoad {
let mut true_center = PolyLine::new(self.center_points.clone()).expect(&id.to_string());
match (sidewalk_right, sidewalk_left) {
(Some(w), None) => {
true_center = driving_side.must_right_shift(true_center, w / 2.0);
true_center = true_center.must_shift_right(w / 2.0);
}
(None, Some(w)) => {
true_center = driving_side.must_left_shift(true_center, w / 2.0);
true_center = true_center.must_shift_right(w / 2.0);
}
_ => {}
}
@ -358,51 +350,6 @@ pub enum DrivingSide {
Left,
}
impl DrivingSide {
// "right" and "left" here are in terms of DrivingSide::Right, what I'm used to reasoning about
// in the USA. They invert appropriately for DrivingSide::Left.
pub fn right_shift(self, pl: PolyLine, width: Distance) -> Result<PolyLine, String> {
match self {
DrivingSide::Right => pl.shift_right(width),
DrivingSide::Left => pl.shift_left(width),
}
}
pub fn must_right_shift(self, pl: PolyLine, width: Distance) -> PolyLine {
self.right_shift(pl, width).unwrap()
}
pub fn left_shift(self, pl: PolyLine, width: Distance) -> Result<PolyLine, String> {
match self {
DrivingSide::Right => pl.shift_left(width),
DrivingSide::Left => pl.shift_right(width),
}
}
pub fn must_left_shift(self, pl: PolyLine, width: Distance) -> PolyLine {
self.left_shift(pl, width).unwrap()
}
pub fn right_shift_line(self, line: Line, width: Distance) -> Line {
match self {
DrivingSide::Right => line.shift_right(width),
DrivingSide::Left => line.shift_left(width),
}
}
pub fn left_shift_line(self, line: Line, width: Distance) -> Line {
match self {
DrivingSide::Right => line.shift_left(width),
DrivingSide::Left => line.shift_right(width),
}
}
pub fn angle_offset(self, a: Angle) -> Angle {
match self {
DrivingSide::Right => a,
DrivingSide::Left => a.opposite(),
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct RawBusRoute {
pub full_name: String,

View File

@ -548,10 +548,7 @@ impl Pedestrian {
orig_angle.opposite()
};
(
pos.project_away(
SIDEWALK_THICKNESS / 4.0,
map.driving_side_angle(facing.rotate_degs(90.0)),
),
pos.project_away(SIDEWALK_THICKNESS / 4.0, facing.rotate_degs(90.0)),
facing,
)
}
@ -563,10 +560,7 @@ impl Pedestrian {
orig_angle
};
(
pos.project_away(
SIDEWALK_THICKNESS / 4.0,
map.driving_side_angle(facing.rotate_degs(90.0)),
),
pos.project_away(SIDEWALK_THICKNESS / 4.0, facing.rotate_degs(90.0)),
facing,
)
}
@ -620,11 +614,8 @@ impl Pedestrian {
let (pt, angle) = self.goal.sidewalk_pos.pt_and_angle(map);
// Stand on the far side of the sidewalk (by the bus stop), facing the road
(
pt.project_away(
SIDEWALK_THICKNESS / 4.0,
map.driving_side_angle(angle.rotate_degs(90.0)),
),
map.driving_side_angle(angle.rotate_degs(-90.0)),
pt.project_away(SIDEWALK_THICKNESS / 4.0, angle.rotate_degs(90.0)),
angle.rotate_degs(-90.0),
)
}
};