Runs in O(n) allocations: one bool‐array + one index stack + one output vector
| 128 | // Runs in O(n) allocations: one bool‐array + one index stack + one output |
| 129 | // vector |
| 130 | void simplifyInternal(const fl::span<const Point> &polyLine) { |
| 131 | mSimplified.clear(); |
| 132 | int n = polyLine.size(); |
| 133 | if (n < 2) { |
| 134 | if (n) { |
| 135 | mSimplified.assign(polyLine.data(), polyLine.data() + n); |
| 136 | } |
| 137 | return; |
| 138 | } |
| 139 | const NumberT minDist2 = mMinDistance * mMinDistance; |
| 140 | |
| 141 | // mark all points as “kept” initially |
| 142 | keep.assign(n, 1); |
| 143 | |
| 144 | // explicit stack of (start,end) index pairs |
| 145 | indexStack.clear(); |
| 146 | // indexStack.reserve(64); |
| 147 | indexStack.push_back({0, n - 1}); |
| 148 | |
| 149 | // process segments |
| 150 | while (!indexStack.empty()) { |
| 151 | // auto [i0, i1] = indexStack.back(); |
| 152 | auto pair = indexStack.back(); |
| 153 | int i0 = pair.first; |
| 154 | int i1 = pair.second; |
| 155 | indexStack.pop_back(); |
| 156 | const bool has_interior = (i1 - i0) > 1; |
| 157 | if (!has_interior) { |
| 158 | // no interior points, just keep the endpoints |
| 159 | // keep[i0] = 1; |
| 160 | // keep[i1] = 1; |
| 161 | continue; |
| 162 | } |
| 163 | |
| 164 | // find farthest point in [i0+1 .. i1-1] |
| 165 | NumberT maxDist2 = 0; |
| 166 | int split = i0; |
| 167 | for (int i = i0 + 1; i < i1; ++i) { |
| 168 | if (!keep[i]) |
| 169 | continue; |
| 170 | NumberT d2 = PerpendicularDistance2(polyLine[i], polyLine[i0], |
| 171 | polyLine[i1]); |
| 172 | |
| 173 | // FL_WARN("Perpendicular distance2 between " |
| 174 | // << polyLine[i] << " and " << polyLine[i0] |
| 175 | // << " and " << polyLine[i1] << " is " << d2); |
| 176 | |
| 177 | if (d2 > maxDist2) { |
| 178 | maxDist2 = d2; |
| 179 | split = i; |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | if (maxDist2 > minDist2) { |
| 184 | // need to keep that split point and recurse on both halves |
| 185 | indexStack.push_back({i0, split}); |
| 186 | indexStack.push_back({split, i1}); |
| 187 | } else { |