mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-22 19:08:51 +00:00
Skip missing segments when starting a region loop walk
Fixes #449 Co-Authored-By: Claude Haiku 5.5 <[email protected]> Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
8482c3e85b
commit
ef10edfe29
2 files changed
+25
-2
No files matched your search
@@ -18,8 +18,9 @@ impl VectorNetwork {
|
||||
/// second; a segment that doesn't touch the point reached so far (a malformed loop) is taken
|
||||
/// as stored. Missing segments are skipped.
|
||||
pub fn loop_walk(&self, lp: &[usize]) -> Vec<(usize, bool)> {
|
||||
let Some(first) = lp.first().and_then(|i| self.segments.get(*i)) else { return Vec::new() };
|
||||
let forward_first = match lp.get(1).and_then(|i| self.segments.get(*i)) {
|
||||
let mut existing = lp.iter().filter_map(|i| self.segments.get(*i));
|
||||
let Some(first) = existing.next() else { return Vec::new() };
|
||||
let forward_first = match existing.next() {
|
||||
Some(second) => first.b == second.a || first.b == second.b,
|
||||
None => true,
|
||||
};
|
||||
|
||||
@@ -148,6 +148,28 @@ fn a_loop_that_does_not_close_is_closed_implicitly() {
|
||||
assert_eq!(n.region_at(p(300.0, 100.0)), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_segments_are_skipped_wherever_they_sit_in_a_loop() {
|
||||
use figcraft_geom::Shape;
|
||||
let mut n = VectorNetwork::default();
|
||||
square(&mut n, 0.0, 0.0, 200.0);
|
||||
n.regions = vec![region(vec![vec![0, 1, 2]], WindingRule::NonZero)];
|
||||
let control = n.region_path(0).unwrap();
|
||||
let control_walk = n.loop_walk(&[0, 1, 2]);
|
||||
for lp in [vec![99, 0, 1, 2], vec![0, 99, 1, 2], vec![99, 98, 0, 1, 2]] {
|
||||
n.regions = vec![region(vec![lp.clone()], WindingRule::NonZero)];
|
||||
assert_eq!(n.loop_walk(&lp), control_walk, "{lp:?}");
|
||||
assert_eq!(n.region_at(p(100.0, 100.0)), Some(0), "{lp:?}");
|
||||
assert!(n.region_contains(0, p(100.0, 100.0)), "{lp:?}");
|
||||
let path = n.region_path(0).unwrap();
|
||||
assert_eq!(path.elements().len(), control.elements().len(), "{lp:?}");
|
||||
assert!((path.area().abs() - control.area().abs()).abs() < 1e-6, "{lp:?}");
|
||||
}
|
||||
n.regions = vec![region(vec![vec![99]], WindingRule::NonZero)];
|
||||
assert!(n.region_path(0).is_none());
|
||||
assert!(!n.region_contains(0, p(100.0, 100.0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_regions_points_are_listed_once() {
|
||||
let mut n = nested();
|
||||
|
||||
Reference in new issue
Block a user