简体   繁体   中英

Find maximum for Point3f in vector of vector

I saw a bit similar question here but I didn't get what I am looking for. I have something like this

vector< vector<Point3f> > 3dpoints;

Now lets say I want to find the maximum only for x coordinates and want to print all other values associate to it. I tried like below but it is throwing some error request for member 'begin' ...

for( auto r = 0; r < 3dpoints.size(); r++ ) {
    for( auto s = 0; s < 3dpoints[r].size(); s++ ) {
        cout<< max_element( 3dpoints[r][s].x.begin(), 3dpoints[r][s].x.end() ) << endl; 
    } 
}

I know I am missing something basic but can't get it. Can anyone help me to find max in Point3f?

template<class F>
struct projected_order_t {
  F f;
  template<class Lhs, class Rhs>
  bool operator()(Lhs const& lhs, Rhs const& rhs)const {
    return f(lhs) < f(rhs);
  }
};
template<class F>
projected_order_t<F> projected_order(F f) {
  return {std::move(f)};
}

auto max_elem_of_vector = [](std::vector<Point3f> const& pts){
  return std::max_element( pts.begin(), pts.end(), projected_order(
    [](Point3f pt){ return pt.x; }
  ));
};
auto max_x_of_vector = [](std::vector<Point3f> const& pts){
  auto it = max_elem_of_vector(pts);
  if (it == pts.end()) return std::numeric_limits<float>::min();
  return it->x;
};
auto max_elem_of_v_of_v = [](std::vector<std::vector<Point3f>> const& pts){
  auto it = std::max_element( pts.begin(), pts.end(), projected_order(
    max_x_of_vector
  ));
  auto minf = std::numeric_limits<float>::min();
  auto minp = Point3f{minf, minf, minf};
  if (it == pts.end())
    return minp
  auto it2 = max_elem_of_vector(*it);
  if (it2 == it->end()) 
    return minp;
  return *it2;
};

max_elem_of_v_of_v should solve your problem.

Projected order takes a projection (a mapping from type A to type B), and returns an ordering on type A that uses the mapping to B and < on B .

The first use maps a point to its x coordinate; this lets us find the max element in a vector of points by the x coordinate.

The second use maps a vector of points to the max x of any element in that vector. We use that to find the vector with the largest x element.

We then extract the element from that maximal vector with the largest x element.

It returns min float values if there is no min element.

You can do that with single pass:

vector< vector<Point3f> > points;
vector<Point3f> maxes;
for( const auto &v : points ) {
    for( const auto &p : v ) {
        if( not maxes.empty() and maxes.front().x < p.x )
            maxes.clear();
        if( maxes.empty() or maxes.front().x == p.x )
            maxes.push_back( p );
    }
}
// here you have list of all points with max x in maxes

This is an example to show the idea, in your code you probably want to replace < and == with function using epsilon to properly compare floating numbers.

PS code shown do that for all data, you mention that you need to do that for each row individually. Code can be easily changed to do that:

for( const auto &v : points ) {
    vector<Point3f> maxes;
    for( const auto &p : v ) {
        if( not maxes.empty() and maxes.front().x < p.x )
            maxes.clear();
        if( maxes.empty() or maxes.front().x == p.x )
            maxes.push_back( p );
    }
    // print maxes here
}

Based on your latest comments the code should be:

for( auto r = 0; r < 3dpoints.size(); r++ ) {
   auto highest = max_element(begin(3dpoints[r]), end(3dpoints[r]),
                              [](const Point3f &lhs, const Point3f &rhs) 
                                { return lhs.x < rhs.x; })
   cout << highest->y << highest->z << endl;
}

What you are doing wrong:

  • 3dpoints[r][s].x is a float, does not have begin()/end().
  • you need to provide a custom compare function for max_element.

EDIT Thanks @Slava for pointing out that std::max_element returns an iterator.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM