Guest User

Untitled

a guest
Oct 17th, 2018
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.38 KB | None | 0 0
  1. std::vector<Point> DouglasPeucker(const std::vector<Point>& pts, const double tolerance) {
  2.  
  3. std::vector<Point> result_pts;
  4.  
  5. struct StackElement {
  6. Point pt;
  7. size_t idx;
  8. };
  9.  
  10. {
  11. std::vector<StackElement> dpStack;
  12. result_pts.resize(0);
  13. // size == 8 is some arbitrary size at which simplification probably
  14. // isn't worth it.
  15. if (pts.empty() || pts.size() <= 100) {
  16. return std::vector<Point>(pts);
  17. }
  18.  
  19. dpStack.reserve(pts.size());
  20.  
  21. Point anchor = pts.front();
  22. size_t anchor_idx = 0;
  23. Point floater = pts.back();
  24. size_t floater_idx = pts.size() - 2;
  25. // many items submitted to this are closed loops,
  26. // whose first + last points are equivalent. this
  27. // will cause divide by zero errors when finding distance below
  28. if (floater == anchor) {
  29. floater = pts[floater_idx - 1];
  30. }
  31.  
  32. result_pts.push_back(anchor);
  33.  
  34. StackElement elem{
  35. floater,
  36. floater_idx,
  37. };
  38.  
  39. dpStack.push_back(elem);
  40.  
  41. while (!dpStack.empty()) {
  42.  
  43. double max_distSq = 0.0;
  44. Point furthest = anchor;
  45. size_t furthest_idx = anchor_idx;
  46.  
  47. // find point furthest from line seg created by (anchor, floater) and note it
  48. for (size_t i = anchor_idx + 1; i < floater_idx; ++i) {
  49. const double dist = static_cast<double>(GetDistSqFromLine(pts[i], pts[anchor_idx], pts[floater_idx]));
  50. if (dist > max_distSq) {
  51. max_distSq = dist;
  52. furthest = pts[i];
  53. furthest_idx = i;
  54. }
  55. }
  56.  
  57. // remove point if less than tolerance
  58. if (max_distSq <= tolerance) {
  59. result_pts.push_back(dpStack.back().pt);
  60. dpStack.pop_back();
  61. anchor = floater;
  62. anchor_idx = floater_idx;
  63. if (!dpStack.empty()) {
  64. floater = dpStack.back().pt;
  65. floater_idx = dpStack.back().idx;
  66. }
  67. }
  68. else {
  69. floater = furthest;
  70. floater_idx = furthest_idx;
  71. elem.pt = floater;
  72. elem.idx = floater_idx;
  73. dpStack.push_back(elem);
  74. }
  75. }
  76. }
  77.  
  78. return result_pts;
  79. }
Add Comment
Please, Sign In to add comment