| 249 | |
| 250 | template <typename VectorType = fl::vector<Point>> |
| 251 | void simplify(const fl::span<const Point> &polyLine, VectorType *out) { |
| 252 | if (mCount > polyLine.size()) { |
| 253 | safeCopy(polyLine, out); |
| 254 | return; |
| 255 | } else if (mCount == polyLine.size()) { |
| 256 | safeCopy(polyLine, out); |
| 257 | return; |
| 258 | } else if (mCount < 2) { |
| 259 | fl::vector_fixed<Point, 2> temp; |
| 260 | if (polyLine.size() > 0) { |
| 261 | temp.push_back(polyLine[0]); |
| 262 | } |
| 263 | if (polyLine.size() > 1) { |
| 264 | temp.push_back(polyLine[polyLine.size() - 1]); |
| 265 | } |
| 266 | out->assign(temp.begin(), temp.end()); |
| 267 | return; |
| 268 | } |
| 269 | NumberT est_max_dist = estimateMaxDistance(polyLine); |
| 270 | NumberT min = 0; |
| 271 | NumberT max = est_max_dist; |
| 272 | NumberT mid = (min + max) / 2.0f; |
| 273 | while (true) { |
| 274 | // min < max; |
| 275 | auto diff = max - min; |
| 276 | const bool done = (diff < 0.01f); |
| 277 | out->clear(); |
| 278 | mLineSimplifier.setMinimumDistance(mid); |
| 279 | mLineSimplifier.simplify(polyLine, out); |
| 280 | |
| 281 | fl::size n = out->size(); |
| 282 | |
| 283 | if (n == mCount) { |
| 284 | return; // we are done |
| 285 | } |
| 286 | |
| 287 | // Handle the last few iterations manually. Often the algo will get |
| 288 | // stuck here. |
| 289 | if (n == mCount + 1) { |
| 290 | // Just one more left, so peel it off. |
| 291 | mLineSimplifier.removeOneLeastError(out); |
| 292 | return; |
| 293 | } |
| 294 | |
| 295 | if (n == mCount + 2) { |
| 296 | // Just two more left, so peel them off. |
| 297 | mLineSimplifier.removeOneLeastError(out); |
| 298 | mLineSimplifier.removeOneLeastError(out); |
| 299 | return; |
| 300 | } |
| 301 | |
| 302 | if (done) { |
| 303 | while (out->size() > mCount) { |
| 304 | // we have too many points, so we need to increase the |
| 305 | // distance |
| 306 | mLineSimplifier.removeOneLeastError(out); |
| 307 | } |
| 308 | return; |
nothing calls this directly
no test coverage detected