From c6a4b6aba0de4d6ac612515cc9fb70307157c9ed Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Fri, 18 Apr 2025 00:15:43 +0200 Subject: [PATCH] Added a new utility function --- src/db/db/dbPLCTriangulation.cc | 35 ++++++++++++++++++-- src/db/db/dbPLCTriangulation.h | 31 ++++++++++------- src/db/unit_tests/dbPLCTriangulationTests.cc | 30 +++++++++++++++++ 3 files changed, 81 insertions(+), 15 deletions(-) diff --git a/src/db/db/dbPLCTriangulation.cc b/src/db/db/dbPLCTriangulation.cc index 90f68d296..d148656a6 100644 --- a/src/db/db/dbPLCTriangulation.cc +++ b/src/db/db/dbPLCTriangulation.cc @@ -294,7 +294,7 @@ Triangulation::find_triangle_for_point (const db::DPoint &point) } Edge * -Triangulation::find_closest_edge (const db::DPoint &p, Vertex *vstart, bool inside_only) +Triangulation::find_closest_edge (const db::DPoint &p, Vertex *vstart, bool inside_only) const { if (!vstart) { @@ -1057,7 +1057,7 @@ Triangulation::search_edges_crossing (Vertex *from, Vertex *to) } Vertex * -Triangulation::find_vertex_for_point (const db::DPoint &point) +Triangulation::find_vertex_for_point (const db::DPoint &point) const { Edge *edge = find_closest_edge (point); if (!edge) { @@ -1073,7 +1073,7 @@ Triangulation::find_vertex_for_point (const db::DPoint &point) } Edge * -Triangulation::find_edge_for_points (const db::DPoint &p1, const db::DPoint &p2) +Triangulation::find_edge_for_points (const db::DPoint &p1, const db::DPoint &p2) const { Vertex *v = find_vertex_for_point (p1); if (!v) { @@ -1087,6 +1087,35 @@ Triangulation::find_edge_for_points (const db::DPoint &p1, const db::DPoint &p2) return 0; } +std::vector +Triangulation::find_vertexes_along_line (const db::DPoint &p1, const db::DPoint &p2) const +{ + db::DEdge e12 (p1, p2); + + Vertex *v = find_vertex_for_point (p1); + if (!v) { + v = find_vertex_for_point (p2); + e12.swap_points (); + } + + std::vector result; + + while (v) { + Vertex *vn = 0; + for (auto e = v->begin_edges (); e != v->end_edges (); ++e) { + Vertex *vv = (*e)->other (v); + if (db::vprod_sign (e12.d (), *vv - *v) == 0 && db::sprod_sign (e12.d (), *vv - *v) > 0 && db::sprod_sign (e12.d (), *vv - e12.p2 ()) < 0) { + result.push_back (vv); + vn = vv; + break; + } + } + v = vn; + } + + return result; +} + static bool is_touching (const db::DEdge &a, const db::DEdge &b) { return (a.side_of (b.p1 ()) == 0 || a.side_of (b.p2 ()) == 0); diff --git a/src/db/db/dbPLCTriangulation.h b/src/db/db/dbPLCTriangulation.h index b3e941f89..af17aa876 100644 --- a/src/db/db/dbPLCTriangulation.h +++ b/src/db/db/dbPLCTriangulation.h @@ -158,6 +158,23 @@ public: */ Vertex *insert_point (const db::DPoint &point, std::list > *new_triangles = 0); + /** + * @brief Finds the edge for two given points + */ + Edge *find_edge_for_points (const db::DPoint &p1, const db::DPoint &p2) const; + + /** + * @brief Finds the vertex for a point + */ + Vertex *find_vertex_for_point (const db::DPoint &pt) const; + + /** + * @brief Finds the vertexes along the line given from p1 and p2 + * + * At least one of the points p1 and p2 must be existing vertexes. + */ + std::vector find_vertexes_along_line (const db::DPoint &p1, const db::DPoint &p2) const; + /** * @brief Statistics: number of flips (fixing) */ @@ -216,16 +233,6 @@ protected: */ std::vector search_edges_crossing (Vertex *from, Vertex *to); - /** - * @brief Finds the edge for two given points - */ - Edge *find_edge_for_points (const db::DPoint &p1, const db::DPoint &p2); - - /** - * @brief Finds the vertex for a point - */ - Vertex *find_vertex_for_point (const db::DPoint &pt); - /** * @brief Ensures all points between from an to are connected by edges and makes these segments */ @@ -275,7 +282,7 @@ private: bool m_is_constrained; size_t m_level; size_t m_id; - size_t m_flips, m_hops; + mutable size_t m_flips, m_hops; template void make_contours (const Poly &poly, const Trans &trans, std::vector > &contours); @@ -284,7 +291,7 @@ private: std::vector fill_concave_corners (const std::vector &edges); void fix_triangles (const std::vector &tris, const std::vector &fixed_edges, std::list > *new_triangles); std::vector find_triangle_for_point (const db::DPoint &point); - Edge *find_closest_edge (const db::DPoint &p, Vertex *vstart = 0, bool inside_only = false); + Edge *find_closest_edge (const db::DPoint &p, Vertex *vstart = 0, bool inside_only = false) const; Vertex *insert (Vertex *vertex, std::list > *new_triangles = 0); void split_triangle (Polygon *t, Vertex *vertex, std::list > *new_triangles_out); void split_triangles_on_edge (Vertex *vertex, Edge *split_edge, std::list > *new_triangles_out); diff --git a/src/db/unit_tests/dbPLCTriangulationTests.cc b/src/db/unit_tests/dbPLCTriangulationTests.cc index ae8856bb4..9253eb0ce 100644 --- a/src/db/unit_tests/dbPLCTriangulationTests.cc +++ b/src/db/unit_tests/dbPLCTriangulationTests.cc @@ -146,6 +146,36 @@ TEST(insert_vertex_twice) EXPECT_EQ (tris.check(), true); } +TEST(collect_vertexes) +{ + db::plc::Graph plc; + TestableTriangulation tris (&plc); + tris.init_box (db::DBox (0, 0, 1, 1)); + tris.insert_point (0.2, 0.2); + tris.insert_point (0.5, 0.5); + + std::vector vertexes = tris.find_vertexes_along_line (db::DPoint (0, 0), db::DPoint (1.5, 1.5)); + EXPECT_EQ (vertexes.size (), size_t (3)); + if (vertexes.size () >= size_t (3)) { + EXPECT_EQ (vertexes [0]->to_string (), "(0.2, 0.2)"); + EXPECT_EQ (vertexes [1]->to_string (), "(0.5, 0.5)"); + EXPECT_EQ (vertexes [2]->to_string (), "(1, 1)"); + } + + vertexes = tris.find_vertexes_along_line (db::DPoint (0, 0), db::DPoint (1.0, 1.0)); + EXPECT_EQ (vertexes.size (), size_t (2)); + if (vertexes.size () >= size_t (2)) { + EXPECT_EQ (vertexes [0]->to_string (), "(0.2, 0.2)"); + EXPECT_EQ (vertexes [1]->to_string (), "(0.5, 0.5)"); + } + + vertexes = tris.find_vertexes_along_line (db::DPoint (1, 1), db::DPoint (0.25, 0.25)); + EXPECT_EQ (vertexes.size (), size_t (1)); + if (vertexes.size () >= size_t (1)) { + EXPECT_EQ (vertexes [0]->to_string (), "(0.5, 0.5)"); + } +} + TEST(insert_vertex_convex) { db::plc::Graph plc;