当前位置:  开发笔记 > 编程语言 > 正文

如何将STD :: List中最近的"Point"对象删除为某些x,y?

如何解决《如何将STD::List中最近的"Point"对象删除为某些x,y?》经验,为你挑选了1个好方法。

我有一个点类:

class Point {
public:
    int x, y;
    Point(int x1, int y1)
    {
        x = x1;
        y = y1;
    }
};

和一个点列表:

std::list  pointList;
std::list ::iterator iter;

我正在将点数推到我的pointList(尽管如果没有推送列表,列表可能还没有包含点数).

我有两个问题:

如何从列表中删除最接近某个(x,y)的点?

假设我有x,y(5,12),我想找到最接近该点的列表中的Point并将其从STD :: List中删除.

我知道我将不得不使用距离公式,我将不得不使用迭代器迭代列表,但是我在描述如何跟踪哪个点最接近我在迭代列表时遇到了一些麻烦.

如何返回给定(x,y)x半径内的数组或点列表?

类似于上一个问题,除了我需要一个指向给定(x,y)的5个半径内的"点"对象的指针列表.另外,我应该返回一个数组还是一个List?

如果有人可以帮助我,我仍然在努力通过C++,我很感激.



1> Judge Maygar..:

在循环遍历列表时,使用std :: list :: iterator变量来跟踪最近的点.当您到达列表的末尾时,它将包含最近的点,并可用于擦除项目.

void erase_closest_point(const list& pointList, const Point& point)
{
    if (!pointList.empty())
    {
        list::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::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& radiusListOutput,
                               const list& pointList,
                               const Point& center, float radius)
{
    // for each point in the list
    for (list::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);
        }
    }
}

再次使用copy if:

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& radiusListOutput,
                               const list& pointList,
                               const Point& center, float radius)
{
    radiusListOutput.reserve(pointList.size());
    remove_copy_if(pointList.begin(), pointList.end(),
                   radiusListOutput.begin(),
                   RadiusChecker(center, radius));
}

请注意,如果您需要额外的性能,可以删除sqrt,因为幅度的平方对于这些比较同样适用.此外,如果您真的想要提高性能而不是考虑允许像四叉树这样的场景分区的数据结构.第一个问题与碰撞检测密切相关,并且有大量有关该主题的有价值信息.

推荐阅读
Life一切安好
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有