Reputation: 143
I have two classes Entity
and Ship
. Ship
is inherited from Entity
. They have x
and y
as attributes which represents there position on 2D plane.
squared_distance
function returns distance between a ship and an entity.
class Entity
{
public:
int id, x, y;
Entity(int id, int x, int y) : id(id), x(x), y(y) {}
};
class Ship : public Entity
{
public:
int orientation, speed, rum;
Ship(int id, int x, int y, int ori, int s, int r):
Entity(id, x, y)
{
orientation = ori;
speed = s;
rum = r;
}
};
int squared_distance(Entity e, Ship s)
{
return pow((e.x - s.x), 2) + pow((e.y - s.y), 2);
}
I need to find the nearest entity to the ship. I have an array of Entity
named entities
. One way to do that is:
Let ship
is object of Ship
.
index
will give the index of nearest entity to the ship
.
int min_distance = 10000000;
int index;
for (int i = 0; i < entities.size(); ++i)
{
int curr_distance = squared_distance(entities[i], ship);
if (curr_distance < min_distance)
{
min_distance = curr_distance;
index = i;
}
}
How to find nearest enity using lambda with std::min_element
in algorithm library?
Upvotes: 0
Views: 599
Reputation: 60228
You can convert this to std::min_element
like this:
auto closer = [&ship](const auto &e1, const auto &e2) {
return squared_distance(e1, ship)
< squared_distance(e2, ship);
};
auto it = std::min_element(std::begin(entities), std::end(entities), closer);
Note that this algorithm (like most algorithms), will return an iterator
to the closest ship. You can get the closest ship by dereferencing this iterator:
auto closest_ship = *it;
You can also get the index of this ship (as you have in your version):
int i = std::distance(std::begin(entities), it);
As @S.M. points out in their answer, your squared_distance
function should take its parameters by const&
, since you don't need to make a copy of those objects in order to compare them.
Upvotes: 2
Reputation: 311038
Something like
#include <iterator>
#include <algorithm>
//...
auto it = std::min_element( std::begin( entities ), std::end( entities ),
[&ship]( const auto &first, const auto &second )
{
return squared_distance( first, ship ) < squared_distance( second, ship );
} );
You can define the lambda separately like for example
auto less_distance = [&ship]( const auto &first, const auto &second )
{
return squared_distance( first, ship ) < squared_distance( second, ship );
};
Then the call of the algorithm will look like
auto it = std::min_element( std::begin( entities ), std::end( entities ),
less_distance );
Upvotes: 1
Reputation: 38539
int squared_distance(const Entity& e, const Ship& s)
{
return pow((e.x - s.x), 2) + pow((e.y - s.y), 2);
}
std::min_element(std::begin(entities), std::end(entities), [&ship](const Entity& a, const Entity& b) { return squared_distance(a, ship) < squared_distance(b, ship); });
Note you need to update parameters in your squared_distance
declaration.
Upvotes: 2