adjust the indication of some selected objects

This commit is contained in:
Dustin Carlino 2020-02-10 13:16:39 -08:00
parent dd9667b95e
commit f359995a27
4 changed files with 67 additions and 6 deletions

View File

@ -13,7 +13,7 @@ use ezgui::{
};
use geom::{Circle, Distance, Duration, Statistic, Time};
use map_model::{IntersectionID, RoadID};
use sim::{CarID, TripEnd, TripID, TripMode, TripStart};
use sim::{CarID, TripEnd, TripID, TripMode, TripStart, VehicleType};
use std::collections::BTreeMap;
pub struct InfoPanel {
@ -107,10 +107,41 @@ impl InfoPanel {
&mut ui.primary.draw_map.agents.borrow_mut(),
ctx.prerender,
) {
batch.push(
ui.cs.get_def("current object", Color::BLUE),
obj.get_outline(&ui.primary.map),
);
// Different selection styles for different objects.
match id {
ID::Car(_) | ID::Pedestrian(_) | ID::PedCrowd(_) => {
// Some objects are much wider/taller than others
let multiplier = match id {
ID::Car(c) => {
if c.1 == VehicleType::Bike {
3.0
} else {
0.75
}
}
ID::Pedestrian(_) => 3.0,
ID::PedCrowd(_) => 0.75,
_ => unreachable!(),
};
// Make a circle to cover the object.
let bounds = obj.get_outline(&ui.primary.map).get_bounds();
let radius = multiplier * Distance::meters(bounds.width().max(bounds.height()));
batch.push(
ui.cs.get_def("current object", Color::WHITE).alpha(0.5),
Circle::new(bounds.center(), radius).to_polygon(),
);
batch.push(
ui.cs.get("current object"),
Circle::outline(bounds.center(), radius, Distance::meters(0.3)),
);
// TODO And actually, don't cover up the agent. The Renderable API isn't quite
// conducive to doing this yet.
}
_ => {
batch.push(Color::BLUE, obj.get_outline(&ui.primary.map));
}
}
}
// Show relationships between some objects

View File

@ -75,6 +75,12 @@ impl Bounds {
pub fn height(&self) -> f64 {
self.max_y - self.min_y
}
pub fn center(&self) -> Pt2D {
Pt2D::new(
self.min_x + self.width() / 2.0,
self.min_y + self.height() / 2.0,
)
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]

View File

@ -1,4 +1,4 @@
use crate::{Angle, Bounds, Distance, Polygon, Pt2D};
use crate::{Angle, Bounds, Distance, Polygon, Pt2D, Ring};
use serde_derive::{Deserialize, Serialize};
use std::fmt;
@ -55,6 +55,27 @@ impl Circle {
}
Polygon::precomputed(pts, indices)
}
pub fn outline(center: Pt2D, radius: Distance, thickness: Distance) -> Polygon {
assert!(radius > thickness);
// TODO This impl doesn't work because there's a weird edge
if false {
let mut pts = Circle::new(center, radius).to_polygon().points().clone();
pts.push(pts[0]);
return Ring::new(pts).make_polygons(thickness);
}
// TODO Argh this one also leaves a little piece missing, but it looks less bad. Fine.
let bigger = Circle::new(center, radius).to_polygon();
let smaller = Circle::new(center, radius - thickness).to_polygon();
let mut polygons = bigger.difference(&smaller);
let mut result = polygons.pop().unwrap();
for p in polygons {
result = result.union(p);
}
result
}
}
impl fmt::Display for Circle {

View File

@ -254,6 +254,9 @@ impl Polygon {
pub fn intersection(&self, other: &Polygon) -> Vec<Polygon> {
from_multi(to_geo(self.points()).intersection(&to_geo(other.points())))
}
pub fn difference(&self, other: &Polygon) -> Vec<Polygon> {
from_multi(to_geo(self.points()).difference(&to_geo(other.points())))
}
pub fn polylabel(&self) -> Pt2D {
let pt = polylabel::polylabel(&to_geo(&self.points()), &1.0).unwrap();