union make_arrow polygon

This commit is contained in:
Dustin Carlino 2019-05-28 17:58:47 -07:00
parent f2f16ad992
commit 110140f391
10 changed files with 49 additions and 41 deletions

View File

@ -7,7 +7,7 @@ use abstutil::WeightedUsizeChoice;
use ezgui::{
Color, Drawable, EventCtx, GfxCtx, Key, LogScroller, ModalMenu, Wizard, WrappedWizard,
};
use geom::{Distance, Duration, Line, Pt2D};
use geom::{Distance, Duration, PolyLine, Pt2D};
use map_model::{IntersectionID, Map, Neighborhood};
use sim::{BorderSpawnOverTime, OriginDestination, Scenario, SeedParkedCars, SpawnOverTime};
use std::collections::BTreeMap;
@ -177,12 +177,13 @@ impl ScenarioEditor {
if src == dst {
continue;
}
g.draw_arrow(
g.draw_polygon(
// Source color, sure
mapping[&s.start_from_neighborhood].color.alpha(0.5),
// TODO Vary by (relative) number of agents
Distance::meters(100.0),
&Line::new(src, dst),
&PolyLine::new(vec![src, dst])
.make_arrow(Distance::meters(100.0))
.unwrap(),
);
}

View File

@ -78,15 +78,15 @@ impl DrawBike {
if let Some(t) = input.waiting_for_turn {
let angle = map.get_t(t).angle();
for poly in PolyLine::new(vec![
body_pos.project_away(body_radius / 2.0, angle.opposite()),
body_pos.project_away(body_radius / 2.0, angle),
])
.make_arrow(Distance::meters(0.25))
.unwrap()
{
draw_default.push(cs.get("blinker on"), poly);
}
draw_default.push(
cs.get("blinker on"),
PolyLine::new(vec![
body_pos.project_away(body_radius / 2.0, angle.opposite()),
body_pos.project_away(body_radius / 2.0, angle),
])
.make_arrow(Distance::meters(0.25))
.unwrap(),
);
}
DrawBike {

View File

@ -104,7 +104,7 @@ impl DrawCar {
match turn.turn_type {
TurnType::Left | TurnType::LaneChangeLeft => {
for circle in vec![front_left, back_left] {
draw_default.extend(
draw_default.push(
arrow_color,
PolyLine::new(vec![
circle.center.project_away(radius / 2.0, angle.opposite()),
@ -117,7 +117,7 @@ impl DrawCar {
}
TurnType::Right | TurnType::LaneChangeRight => {
for circle in vec![front_right, back_right] {
draw_default.extend(
draw_default.push(
arrow_color,
PolyLine::new(vec![
circle.center.project_away(radius / 2.0, angle.opposite()),

View File

@ -363,7 +363,7 @@ fn draw_signal_cycle_with_icons(cycle: &Cycle, batch: &mut GeomBatch, ctx: &Draw
ctx.cs.get_def("traffic light box", Color::BLACK),
Circle::new(center2, radius).to_polygon(),
);
batch.extend(
batch.push(
color,
PolyLine::new(vec![
center2.project_away(radius, lane_line.angle().rotate_degs(90.0)),
@ -498,7 +498,7 @@ fn calculate_border_arrows(i: &Intersection, r: &Road, timer: &mut Timer) -> Vec
let width = (r.children_forwards.len() as f64) * LANE_THICKNESS;
(r.center_pts.first_line().shift_right(width / 2.0), width)
};
result.extend(
result.push(
// DEGENERATE_INTERSECTION_HALF_LENGTH is 5m...
PolyLine::new(vec![
line.unbounded_dist_along(Distance::meters(-9.5)),
@ -522,7 +522,7 @@ fn calculate_border_arrows(i: &Intersection, r: &Road, timer: &mut Timer) -> Vec
let width = (r.children_backwards.len() as f64) * LANE_THICKNESS;
(r.center_pts.first_line().shift_left(width / 2.0), width)
};
result.extend(
result.push(
PolyLine::new(vec![
line.unbounded_dist_along(Distance::meters(-0.5)),
line.unbounded_dist_along(Distance::meters(-9.5)),

View File

@ -233,7 +233,7 @@ fn calculate_turn_markings(map: &Map, lane: &Lane, timer: &mut Timer) -> Vec<Pol
{
continue;
}
results.extend(
results.push(
PolyLine::new(vec![
common_base.last_pt(),
common_base

View File

@ -92,15 +92,15 @@ impl DrawPedestrian {
if let Some(t) = input.waiting_for_turn {
// A silly idea for peds... use hands to point at their turn?
let angle = map.get_t(t).angle();
for poly in PolyLine::new(vec![
input.pos.project_away(radius / 2.0, angle.opposite()),
input.pos.project_away(radius / 2.0, angle),
])
.make_arrow(Distance::meters(0.25))
.unwrap()
{
draw_default.push(cs.get("blinker on"), poly);
}
draw_default.push(
cs.get("blinker on"),
PolyLine::new(vec![
input.pos.project_away(radius / 2.0, angle.opposite()),
input.pos.project_away(radius / 2.0, angle),
])
.make_arrow(Distance::meters(0.25))
.unwrap(),
);
}
DrawPedestrian {

View File

@ -7,7 +7,7 @@ use map_model::{Map, Turn, TurnID};
pub struct DrawTurn {
pub id: TurnID,
icon_circle: Circle,
icon_arrow: Vec<Polygon>,
icon_arrow: Polygon,
}
impl DrawTurn {
@ -38,7 +38,7 @@ impl DrawTurn {
}
pub fn full_geom(t: &Turn, batch: &mut GeomBatch, color: Color) {
batch.extend(color, t.geom.make_arrow(BIG_ARROW_THICKNESS * 2.0).unwrap());
batch.push(color, t.geom.make_arrow(BIG_ARROW_THICKNESS * 2.0).unwrap());
}
pub fn draw_full(t: &Turn, g: &mut GfxCtx, color: Color) {
@ -68,7 +68,7 @@ impl DrawTurn {
} else {
Line::new(last_line.dist_along(last_len - dash_len), last_line.pt2())
};
batch.extend(
batch.push(
color,
arrow_line
.to_polyline()
@ -101,7 +101,7 @@ impl DrawTurn {
},
self.icon_circle.to_polygon(),
);
batch.extend(arrow_color, self.icon_arrow.clone());
batch.push(arrow_color, self.icon_arrow.clone());
}
pub fn contains_pt(&self, pt: Pt2D) -> bool {

View File

@ -122,7 +122,7 @@ impl<'a> GfxCtx<'a> {
}
pub fn draw_arrow(&mut self, color: Color, thickness: Distance, line: &Line) {
self.draw_polygons(color, &line.to_polyline().make_arrow(thickness).unwrap());
self.draw_polygon(color, &line.to_polyline().make_arrow(thickness).unwrap());
}
pub fn draw_circle(&mut self, color: Color, circle: &Circle) {

View File

@ -150,6 +150,17 @@ impl Polygon {
indices: vec![0, 1, 2, 2, 3, 0],
}
}
pub fn union(self, other: Polygon) -> Polygon {
let mut points = self.points;
let mut indices = self.indices;
let offset = points.len();
points.extend(other.points);
for idx in other.indices {
indices.push(offset + idx);
}
Polygon::precomputed(points, indices)
}
}
impl fmt::Display for Polygon {

View File

@ -421,30 +421,26 @@ impl PolyLine {
polygons
}
// TODO One polygon, please :)
pub fn make_arrow(&self, thickness: Distance) -> Warn<Vec<Polygon>> {
pub fn make_arrow(&self, thickness: Distance) -> Warn<Polygon> {
let head_size = thickness * 2.0;
let triangle_height = head_size / 2.0_f64.sqrt();
if self.length() < triangle_height {
return Warn::warn(
vec![self.make_polygons(thickness)],
self.make_polygons(thickness),
format!("Can't make_arrow of thickness {} for {}", thickness, self),
);
}
let slice = self.exact_slice(Distance::ZERO, self.length() - triangle_height);
let angle = slice.last_pt().angle_to(self.last_pt());
Warn::ok(vec![
slice.make_polygons(thickness),
Polygon::new(&vec![
Warn::ok(slice.make_polygons(thickness).union(Polygon::new(&vec![
self.last_pt(),
self.last_pt()
.project_away(head_size, angle.rotate_degs(-135.0)),
self.last_pt()
.project_away(head_size, angle.rotate_degs(135.0)),
]),
])
])))
}
// TODO Refactor