diff options
Diffstat (limited to 'game')
-rw-r--r-- | game/geoData.cpp | 44 | ||||
-rw-r--r-- | game/geoData.h | 6 |
2 files changed, 48 insertions, 2 deletions
diff --git a/game/geoData.cpp b/game/geoData.cpp index ce88e5b..37abc4c 100644 --- a/game/geoData.cpp +++ b/game/geoData.cpp @@ -290,6 +290,50 @@ GeoData::walkUntil(const PointFace & from, const GlobalPosition2D to, Tester<Wal } void +GeoData::walk(const PointFace & from, GlobalPosition2D to, GlobalPosition2D centre, Consumer<WalkStep> op) const +{ + walkUntil(from, to, centre, [&op](const auto & fh) { + op(fh); + return false; + }); +} + +void +GeoData::walkUntil(const PointFace & from, GlobalPosition2D to, GlobalPosition2D centre, Tester<WalkStep> op) const +{ + WalkStep step { + .current = from.face(this), + }; + if (!step.current.is_valid()) { + const auto entryEdge = findEntry(from.point, to); + if (!entryEdge.is_valid()) { + return; + } + step.current = opposite_face_handle(entryEdge); + } + ArcSegment arc {centre, from.point, to}; + while (step.current.is_valid() && !op(step)) { + step.previous = step.current; + for (const auto next : fh_range(step.current)) { + if (opposite_halfedge_handle(next) == step.exitHalfedge) { + continue; + } + step.current = opposite_face_handle(next); + if (step.current.is_valid()) { + const auto e1 = point(to_vertex_handle(next)); + const auto e2 = point(to_vertex_handle(opposite_halfedge_handle(next))); + if (const auto intersect = arc.crossesLineAt(e1, e2)) { + step.exitHalfedge = next; + step.exitPosition = intersect.value(); + break; + } + } + step.current.reset(); + } + } +} + +void GeoData::boundaryWalk(Consumer<HalfedgeHandle> op) const { boundaryWalk(op, findBoundaryStart()); diff --git a/game/geoData.h b/game/geoData.h index 68ce9a2..e3fc313 100644 --- a/game/geoData.h +++ b/game/geoData.h @@ -74,8 +74,10 @@ public: template<typename T> using Consumer = const std::function<void(const T &)> &; template<typename T> using Tester = const std::function<bool(const T &)> &; - void walk(const PointFace & from, const GlobalPosition2D to, Consumer<WalkStep> op) const; - void walkUntil(const PointFace & from, const GlobalPosition2D to, Tester<WalkStep> op) const; + void walk(const PointFace & from, GlobalPosition2D to, Consumer<WalkStep> op) const; + void walkUntil(const PointFace & from, GlobalPosition2D to, Tester<WalkStep> op) const; + void walk(const PointFace & from, GlobalPosition2D to, GlobalPosition2D centre, Consumer<WalkStep> op) const; + void walkUntil(const PointFace & from, GlobalPosition2D to, GlobalPosition2D centre, Tester<WalkStep> op) const; void boundaryWalk(Consumer<HalfedgeHandle>) const; void boundaryWalk(Consumer<HalfedgeHandle>, HalfedgeHandle start) const; |