mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-24 23:15:24 +03:00
Reorder points when converting a PolyLine to a Polygon, so that the
result is usually a Ring. This gets lanes to render in the GeoJSON export. #440 Ideally all Polygons would be expressed as an outer Ring and some optional inner Rings. There are a few cases where this is hard, and we instead just rely on the triangulation for rendering and point containment and give up on GeoJSON export. Not regenerating all maps yet -- zero screenshot diff, the map file does change, but not sure how.
This commit is contained in:
parent
302ec94e3d
commit
6119042b4f
@ -79,8 +79,8 @@ impl Polygon {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO No guarantee points forms a ring. In fact, the main caller is PolyLine, and it's NOT
|
||||
// true there yet.
|
||||
// TODO No guarantee points forms a ring. In fact, the main caller is from SVG->lyon parsing,
|
||||
// and it's NOT true there yet.
|
||||
pub fn precomputed(points: Vec<Pt2D>, indices: Vec<usize>) -> Polygon {
|
||||
assert!(indices.len() % 3 == 0);
|
||||
Polygon {
|
||||
|
@ -445,13 +445,15 @@ impl PolyLine {
|
||||
result
|
||||
}
|
||||
|
||||
/// The resulting polygon is manually triangulated and doesn't have a valid outer Ring.
|
||||
/// The resulting polygon is manually triangulated and may not have a valid outer Ring (but it
|
||||
/// usually does).
|
||||
pub fn make_polygons(&self, width: Distance) -> Polygon {
|
||||
// TODO How to tune this?
|
||||
self.make_polygons_with_miter_threshold(width, MITER_THRESHOLD)
|
||||
}
|
||||
|
||||
/// The resulting polygon is manually triangulated and doesn't have a valid outer Ring.
|
||||
/// The resulting polygon is manually triangulated and may not have a valid outer Ring (but it
|
||||
/// usually does).
|
||||
pub fn make_polygons_with_miter_threshold(
|
||||
&self,
|
||||
width: Distance,
|
||||
@ -459,22 +461,22 @@ impl PolyLine {
|
||||
) -> Polygon {
|
||||
// TODO Don't use the angle corrections yet -- they seem to do weird things.
|
||||
let side1 = self.shift_with_sharp_angles(width / 2.0, miter_threshold);
|
||||
let side2 = self.shift_with_sharp_angles(-width / 2.0, miter_threshold);
|
||||
let mut side2 = self.shift_with_sharp_angles(-width / 2.0, miter_threshold);
|
||||
assert_eq!(side1.len(), side2.len());
|
||||
|
||||
let side2_offset = side1.len();
|
||||
// Order the points so that they form a ring. No deduplication yet, though.
|
||||
let len = 2 * side1.len();
|
||||
let mut points = side1;
|
||||
side2.reverse();
|
||||
points.extend(side2);
|
||||
points.push(points[0]);
|
||||
let mut indices = Vec::new();
|
||||
|
||||
// Walk along the first side, making two triangles each step. This is easy to understand
|
||||
// with a simple diagram, which I should eventually draw in ASCII art here.
|
||||
for high_idx in 1..self.pts.len() {
|
||||
// Duplicate first point, since that's what graphics layer expects
|
||||
indices.extend(vec![high_idx, high_idx - 1, side2_offset + high_idx - 1]);
|
||||
indices.extend(vec![
|
||||
side2_offset + high_idx,
|
||||
side2_offset + high_idx - 1,
|
||||
high_idx,
|
||||
]);
|
||||
indices.extend(vec![high_idx, high_idx - 1, len - high_idx]);
|
||||
indices.extend(vec![len - high_idx, len - high_idx - 1, high_idx]);
|
||||
}
|
||||
Polygon::precomputed(points, indices)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user