@@ -33,37 +33,46 @@ static double perpendicular_distance(
3333 return std::sqrt ((px - proj_x) * (px - proj_x) + (py - proj_y) * (py - proj_y));
3434}
3535
36- // Recursive Douglas-Peucker
36+ // Iterative Douglas-Peucker (avoids stack overflow on large polylines)
3737static void rdp_simplify (
3838 const compas::RowMatrixXd& polyline,
3939 int start, int end,
4040 double threshold,
4141 std::vector<bool >& keep)
4242{
43- if (end <= start + 1 ) return ;
44-
45- double max_dist = 0.0 ;
46- int max_idx = start;
47-
48- double x1 = polyline (start, 0 );
49- double y1 = polyline (start, 1 );
50- double x2 = polyline (end, 0 );
51- double y2 = polyline (end, 1 );
52-
53- for (int i = start + 1 ; i < end; ++i) {
54- double dist = perpendicular_distance (
55- polyline (i, 0 ), polyline (i, 1 ),
56- x1, y1, x2, y2);
57- if (dist > max_dist) {
58- max_dist = dist;
59- max_idx = i;
43+ std::vector<std::pair<int , int >> stack;
44+ stack.reserve (128 ); // Reasonable default to avoid reallocs
45+ stack.push_back ({start, end});
46+
47+ while (!stack.empty ()) {
48+ auto [seg_start, seg_end] = stack.back ();
49+ stack.pop_back ();
50+
51+ if (seg_end <= seg_start + 1 ) continue ;
52+
53+ double max_dist = 0.0 ;
54+ int max_idx = seg_start;
55+
56+ double x1 = polyline (seg_start, 0 );
57+ double y1 = polyline (seg_start, 1 );
58+ double x2 = polyline (seg_end, 0 );
59+ double y2 = polyline (seg_end, 1 );
60+
61+ for (int i = seg_start + 1 ; i < seg_end; ++i) {
62+ double dist = perpendicular_distance (
63+ polyline (i, 0 ), polyline (i, 1 ),
64+ x1, y1, x2, y2);
65+ if (dist > max_dist) {
66+ max_dist = dist;
67+ max_idx = i;
68+ }
6069 }
61- }
6270
63- if (max_dist > threshold) {
64- keep[max_idx] = true ;
65- rdp_simplify (polyline, start, max_idx, threshold, keep);
66- rdp_simplify (polyline, max_idx, end, threshold, keep);
71+ if (max_dist > threshold) {
72+ keep[max_idx] = true ;
73+ stack.push_back ({seg_start, max_idx});
74+ stack.push_back ({max_idx, seg_end});
75+ }
6776 }
6877}
6978
0 commit comments