/* * pointfilter implementation * * Copyright (C) Dorit Borrmann, Jan Elseberg * * Released under the GPL version 3. * */ #include "slam6d/pointfilter.h" using std::string; using std::map; #include using std::stringstream; #include using std::runtime_error; #include using std::cout; using std::endl; #include map* PointFilter::factory = new map; PointFilter::PointFilter() : m_changed(true), m_checker(0) { } PointFilter::PointFilter(const std::string& params) : m_changed(true), m_checker(0) { size_t start = 0, end = string::npos; while((end = params.find(' ', start)) != string::npos) { // extract the word (start-end+1) without the space (-1) string key(params.substr(start, start-end)); end++; // get the second word position start = params.find(' ', end); // insert m_params[key] = params.substr(end, (start-end)); // advance to the character after space if(start != string::npos) start++; else break; } } PointFilter::~PointFilter() { if(m_checker) delete m_checker; } PointFilter& PointFilter::setRange(double maxDist, double minDist) { m_changed = true; stringstream s_max; s_max << maxDist; stringstream s_min; s_min << minDist; m_params["rangemax"] = s_max.str(); m_params["rangemin"] = s_min.str(); return *this; } PointFilter& PointFilter::setHeight(double top, double bottom) { m_changed = true; stringstream s_top; s_top << top; stringstream s_bottom; s_bottom << bottom; m_params["heighttop"] = s_top.str(); m_params["heightbottom"] = s_bottom.str(); return *this; } PointFilter& PointFilter::setRangeMutator(double range) { m_changed = true; stringstream s_range; s_range << range; m_params["rangemutation"] = s_range.str(); return *this; } std::string PointFilter::getParams() { stringstream s; for(map::iterator it = m_params.begin(); it != m_params.end(); ++it) { s << (*it).first << " " << (*it).second << " "; } return s.str(); } void PointFilter::createCheckers() { // delete the outdated ones if(m_checker) { delete m_checker; m_checker = 0; } // create new ones Checker** current = &m_checker; for(map::iterator it = m_params.begin(); it != m_params.end(); ++it) { *current = (*factory)[it->first](it->second); // if a Checker has been successfully created advance to its pointer in the chain if(*current) { current = &((*current)->m_next); } } } Checker::Checker() : m_next(0) { } Checker::~Checker() { if(m_next) delete m_next; } // create factory instaces for key string to factory function mapping namespace { CheckerFactory max("rangemax"); CheckerFactory min("rangemin"); CheckerFactory top("heighttop"); CheckerFactory bottom("heightbottom"); CheckerFactory range_mutation("rangemutation"); } CheckerRangeMax::CheckerRangeMax(const std::string& value) { stringstream s(value); s >> m_max; // default value: no check if(m_max <= 0.0) throw runtime_error("No range filter needed."); m_max *= m_max; } bool CheckerRangeMax::test(double* point) { if(point[0]*point[0] + point[1]*point[1] + point[2]*point[2] < m_max) return true; return false; } CheckerRangeMin::CheckerRangeMin(const std::string& value) { stringstream s(value); s >> m_min; // default value: no check if(m_min <= 0.0) throw runtime_error("No range filter needed."); m_min *= m_min; } bool CheckerRangeMin::test(double* point) { if(point[0]*point[0] + point[1]*point[1] + point[2]*point[2] > m_min) return true; return false; } CheckerHeightTop::CheckerHeightTop(const std::string& value) { stringstream s(value); s >> m_top; } bool CheckerHeightTop::test(double* point) { if(point[1] < m_top) return true; return false; } CheckerHeightBottom::CheckerHeightBottom(const std::string& value) { stringstream s(value); s >> m_bottom; } bool CheckerHeightBottom::test(double* point) { if(point[1] > m_bottom) return true; return false; } RangeMutator::RangeMutator(const std::string& value) { stringstream s(value); s >> m_range; } bool RangeMutator::test(double* point) { double orig_range = sqrt(point[0]*point[0] + point[1]*point[1] + point[2]*point[2]); double scale_mutation = m_range / orig_range; point[0] *= scale_mutation; point[1] *= scale_mutation; point[2] *= scale_mutation; return true; }