Используйте переменную std :: list :: iterator для отслеживания ближайшей точки при циклическом просмотре списка. Когда вы дойдете до конца списка, он будет содержать ближайшую точку и может быть использован для удаления элемента.
void erase_closest_point(const list<Point>& pointList, const Point& point)
{
if (!pointList.empty())
{
list<Point>::iterator closestPoint = pointList.begin();
float closestDistance = sqrt(pow(point.x - closestPoint->x, 2) +
pow(point.y - closestPoint->y, 2));
// for each point in the list
for (list<Point>::iterator it = closestPoint + 1;
it != pointList.end(); ++it)
{
const float distance = sqrt(pow(point.x - it->x, 2) +
pow(point.y - it->y, 2));
// is the point closer than the previous best?
if (distance < closestDistance)
{
// replace it as the new best
closestPoint = it;
closestDistance = distance
}
}
pointList.erase(closestPoint);
}
}
Построение списка точек в радиусе заданной точки аналогично. Обратите внимание, что пустой список радиусов передается в функцию по ссылке. Добавление точек в список по ссылке избавит от необходимости копировать все точки при возврате вектора по значению.
void find_points_within_radius(vector<Point>& radiusListOutput,
const list<Point>& pointList,
const Point& center, float radius)
{
// for each point in the list
for (list<Point>::iterator it = pointList.begin();
it != pointList.end(); ++it)
{
const float distance = sqrt(pow(center.x - it->x, 2) +
pow(center.y - it->y, 2));
// if the distance from the point is within the radius
if (distance > radius)
{
// add the point to the new list
radiusListOutput.push_back(*it);
}
}
}
Снова используя копию, если:
struct RadiusChecker {
RadiusChecker(const Point& center, float radius)
: center_(center), radius_(radius) {}
bool operator()(const Point& p)
{
const float distance = sqrt(pow(center_.x - p.x, 2) +
pow(center_.y - p.y, 2));
return distance < radius_;
}
private:
const Point& center_;
float radius_;
};
void find_points_within_radius(vector<Point>& radiusListOutput,
const list<Point>& pointList,
const Point& center, float radius)
{
radiusListOutput.reserve(pointList.size());
remove_copy_if(pointList.begin(), pointList.end(),
radiusListOutput.begin(),
RadiusChecker(center, radius));
}
Обратите внимание, что sqrt можно удалить, если вам нужна дополнительная производительность, так как квадрат величины работает также хорошо для этих сравнений. Кроме того, если вы действительно хотите повысить производительность, рассмотрите структуру данных, которая допускает разбиение сцены, например quadtree . Первая проблема тесно связана с обнаружением столкновений , и имеется масса ценной информации по этой теме.