Рекурсивный фильтр throw bad_alloc - PullRequest
0 голосов
/ 16 октября 2018

Следующий код должен отбрасывать точки рядом друг с другом в облаке.Сначала я сортирую точки по расстоянию до определенного центра, затем из ближайшего выбираю только те, которые находятся на определенном расстоянии, чтобы уменьшить плотность, но при работе с ним выдается исключение bad_allocexception, как заставить его работать должным образом?Я тоже пытался использовать mutex recursive_mutex, но это не изменило результат.

#include <iostream>
#include <string>
#include <vector>
#include <math.h>
#include <algorithm>

#define GRID_WIDTH  50

class Point2i{
    public:
       int x;
       int y;
       Point2i(int _x,int _y): x(_x), y(_y){} 
};    

float distanceToPoint(Point2i a, Point2i b)
{
      return sqrt(pow((a.x -b.x),2) + pow((a.y - b.y),2));
};


void selectPoints(const std::vector<Point2i>::iterator  &selector,
                  std::vector<Point2i>            &srcVec,
                  std::vector<Point2i>            &result )
{
      // if the selctor point to the vector
      if(selector != srcVec.end())
      {
           auto p = *selector;
           //add the selector
           result.push_back(p);

           //sort the src Vector assendent based on distance to p
           std::sort(std::begin(srcVec),std::end(srcVec)
                    ,[=](const Point2i& lhs, const Point2i& rhs)
                   {
                       return distanceToPoint(p, lhs) <
                       distanceToPoint(p, rhs);
                    });

           // recursivly check the next point
           for(auto it = selector;; ++it)
           {
                // if the next exist
                if(it != srcVec.end())
                {
                    // check the distance
                    if(distanceToPoint(p,*it) > GRID_WIDTH )
                    {
                         if (srcVec.size() <= 1) return;
                         auto last = srcVec.begin() + srcVec.size();

                         // reduce the vector by discarding all until (*it)
                         std::vector<Point2i> newVec(it,last);
                         // recheck the subvector
                         return selectPoints(it,newVec,result);

                    }//here is the only point to iterate on the for loop
                }
                    //not in vector exit
                else return;
           }
      }
      //not in vector exit
      return;
};

std::vector<Point2i> filterCloud(const Point2i &center, 
                                 std::vector<Point2i> &cloud)
{


     //sort the cloud Vector dessendant based on distance to center
     sort(std::begin(cloud),std::end(cloud)
           ,[=](const Point2i& lhs, const Point2i& rhs)
            {
                return distanceToPoint(center, lhs) > 
                       distanceToPoint(center, rhs);
            });


     std::vector<Point2i> selectedPoints;
     selectPoints(cloud.begin(),cloud,selectedPoints);
     return selectedPoints;          
} 

некоторые образцы:

int main()
{
      Point2i _center(5,5);
      std::vector<Point2i> _cloud = { Point2i(1250,30),
                                      Point2i(10,300),
                                      Point2i(5,3),
                                      Point2i(12,40),
                                      Point2i(150,200),
                                      Point2i(75,75),
                                      Point2i(1025,0)
                                    };



      std::vector<Point2i> result = filterCloud(_center,_cloud);

      for(unsigned int i = 0; i < result.size(); i++)
      {
            std::cout << "Grid point found at : (" + 
                          std::to_string(result[i].x) +" , " + 
                          std::to_string(result[i].y) + ")" << std::endl ;
      }

      return 0;    
}
...