mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-24 09:24:26 +03:00
remove all the polyline shifting/polygon variants that might fail
This commit is contained in:
parent
57665c9325
commit
e8e119dbbf
@ -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() {
|
||||||
|
@ -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),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
|
@ -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) {
|
||||||
|
@ -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() {
|
||||||
|
@ -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)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
|
||||||
|
@ -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() {
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
|
@ -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, ¢er_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");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
|
@ -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(
|
||||||
|
@ -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()
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user