Added a new utility function

This commit is contained in:
Matthias Koefferlein 2025-04-18 00:15:43 +02:00
parent 3ed39e8a4a
commit c6a4b6aba0
3 changed files with 81 additions and 15 deletions

View File

@ -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<Vertex *>
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<Vertex *> 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);

View File

@ -158,6 +158,23 @@ public:
*/
Vertex *insert_point (const db::DPoint &point, std::list<tl::weak_ptr<Polygon> > *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<Vertex *> 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<Edge *> 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<class Poly, class Trans> void make_contours (const Poly &poly, const Trans &trans, std::vector<std::vector<Vertex *> > &contours);
@ -284,7 +291,7 @@ private:
std::vector<Polygon *> fill_concave_corners (const std::vector<Edge *> &edges);
void fix_triangles (const std::vector<Polygon *> &tris, const std::vector<Edge *> &fixed_edges, std::list<tl::weak_ptr<Polygon> > *new_triangles);
std::vector<Polygon *> 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<tl::weak_ptr<Polygon> > *new_triangles = 0);
void split_triangle (Polygon *t, Vertex *vertex, std::list<tl::weak_ptr<Polygon> > *new_triangles_out);
void split_triangles_on_edge (Vertex *vertex, Edge *split_edge, std::list<tl::weak_ptr<Polygon> > *new_triangles_out);

View File

@ -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<db::plc::Vertex *> 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;