Avoid crashing in recalculate_intersection_polygon due to polylines not

containing some points. Happens at i524 in Arboretum and in the West
Seattle proposal.

I don't understand yet why this is possible in the first place, but
crashing is pretty bad in the meantime.
This commit is contained in:
Dustin Carlino 2021-06-19 11:29:01 -07:00
parent 8f199177f5
commit 0bcf01fd05
2 changed files with 44 additions and 2 deletions

View File

@ -752,6 +752,48 @@ impl PolyLine {
}
}
/// Same as get_slice_ending_at, but returns None if the point isn't on the polyline.
// TODO Switch everything to this, after better understanding why this is happening at all.
pub fn safe_get_slice_ending_at(&self, pt: Pt2D) -> Option<PolyLine> {
if self.first_pt() == pt {
return None;
}
if let Some(idx) = self.lines().position(|l| l.contains_pt(pt)) {
let mut pts = self.pts.clone();
pts.truncate(idx + 1);
// Make sure the last line isn't too tiny
if *pts.last().unwrap() == pt {
pts.pop();
}
pts.push(pt);
if pts.len() == 1 {
return None;
}
Some(PolyLine::must_new(pts))
} else {
None
}
}
/// Same as get_slice_starting_at, but returns None if the point isn't on the polyline.
pub fn safe_get_slice_starting_at(&self, pt: Pt2D) -> Option<PolyLine> {
if self.last_pt() == pt {
return None;
}
if let Some(idx) = self.lines().position(|l| l.contains_pt(pt)) {
let mut pts = self.pts.clone();
pts = pts.split_off(idx + 1);
if pt != pts[0] {
pts.insert(0, pt);
}
Some(PolyLine::must_new(pts))
} else {
None
}
}
pub fn dist_along_of_point(&self, pt: Pt2D) -> Option<(Distance, Angle)> {
let mut dist_along = Distance::ZERO;
for l in self.lines() {

View File

@ -567,14 +567,14 @@ fn recalculate_intersection_polygon(
if r.src_i == i {
if let Some(pl) = r
.untrimmed_center_pts
.get_slice_ending_at(trimmed_center_pts.first_pt())
.safe_get_slice_ending_at(trimmed_center_pts.first_pt())
.and_then(|pl| pl.extend(trimmed_center_pts.clone()).ok())
{
trimmed_center_pts = pl;
}
} else if let Some(pl) = r
.untrimmed_center_pts
.get_slice_starting_at(trimmed_center_pts.last_pt())
.safe_get_slice_starting_at(trimmed_center_pts.last_pt())
.and_then(|pl| trimmed_center_pts.clone().extend(pl).ok())
{
trimmed_center_pts = pl;