自定义点类中的ID字段间歇性丢失 [英] ID field intermittently lost in custom point class

查看:76
本文介绍了自定义点类中的ID字段间歇性丢失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个需要处理几何的C ++程序.我一直在尝试使boost::geometry正常工作,但是出现以下问题.我的积分需要维护一个ID值或其他标识标签(我需要将其链接到存储在其他对象中的属性).我可以使用BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET成功注册此点并执行boost::geometry操作,但是当我使用boost::geometry对其执行任何操作时,似乎会创建没有id值的我的点的新副本.

I'm building a C++ program which needs to handle geometry. I have been trying to get boost::geometry to work, but I am having the following issue. My points need to maintain an ID value or other identifying tag (I need to link them to properties stored in other objects). I can successfully register this point using BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET and carry out boost::geometry operations, however the moment I carry out any operations with it boost::geometry seems to create new copies of my point without the id value.

在将boost::geometry与自定义点一起使用时,我是否缺少某些东西,这可能使我可以做我想做的事情,还是必须重新思考我的方法并找到其他做事的方法我想做什么?

Is there something I'm missing about using boost::geometry with custom points that would make it possible to do what I'm trying to do, or do I have to re-think my approach and find some other way to do what I'm trying to do?

下面的代码显示了一个示例点类(int id是标识符),以及一个示例代码,该代码示例可以编译并运行(带有适当的#includenamespace声明),但是它会不断删除我的点ID:

The following code shows an example point class (int id is the identifier) and also a sample of code which compiles and runs (with appropriate #include and namespace declarations) however it keeps removing my point IDs:

积分等级:

class My_Point
{
public:

    My_Point(const My_Point &p);
    My_Point(double x = 0.0, double y = 0.0, int new_id = 0);

    const double Get_X() const;
    const double Get_Y() const;

    void Set_X(double new_x);
    void Set_Y(double new_y);

    const int Get_ID() const;
    void Set_ID(int new_id);

private:
    int id;
    double x;
    double y;
}

复制构造函数:

My_Point::My_Point(const My_Point &p) {
    Set_X(p.Get_X());
    Set_Y(p.Get_Y());
    Set_ID(p.Get_ID());
} 

测试代码:

void TestPolygon()
{
vector < My_Point > p;

p.push_back(My_Point(0.0, 0.0, 0));
p.push_back(My_Point(1.0, 0.0, 1));
p.push_back(My_Point(1.0, 1.0, 2));
p.push_back(My_Point(0.0, 1.0, 3));
p.push_back(My_Point(0.0, 0.0, 4));

cout << "Initial points are:\n";

for (int i = 0, n = p.size(); i < n; i++)
{
    cout << point_to_string(p.at(i)) << "\n";
}

detect_enter();

polygon<My_Point> poly;
append(poly, p);

//this code gives each point with an incorrect id of 0
cout << "Polygon points are:\n";

for (int i = 0, n = poly.outer().size(); i < n; i++)
{
    cout << point_to_string(poly.outer().at(i)) << "\n";
}

detect_enter();

strategy::transform::rotate_transformer<degree, double, 2, 2> rotate(45.0);

for (int i = 0, n = poly.outer().size(); i < n; i++)
{
    transform(poly.outer().at(i), poly.outer().at(i), rotate);
}

vector<My_Point> p2;
p2 = poly.outer();

//this code gives an incorrect id of 0.
cout << "Final points are:\n";

for (int i = 0, n = p2.size(); i < n; i++)
{
    cout << point_to_string(p2.at(i)) << "\n";
}

detect_enter();

//this code gives the correct id values as expected.
cout << "Original points were:\n";

for (int i = 0, n = p.size(); i < n; i++)
{
    cout << point_to_string(p.at(i)) << "\n";
}
}

推荐答案

正如sehe所指出的,该库仅知道如何访问My_Point的X和Y坐标.此外,rotate_transformer只知道如何旋转点的几何部分,它不知道您要存储ID,也不想复制它们.您可以尝试为此编写自己的策略.诸如此类(未经测试):

As sehe pointed out, the library only knows how to access X and Y coordinates of My_Point. Furthermore, the rotate_transformer only knows how to rotate the geometrical part of your Points, it isn't aware that you're storing IDs and that you'd like to copy them. You could try to write your own strategy for this. Something like (not tested):

struct my_rotate_transformer
    : public strategy::transform::rotate_transformer<degree, double, 2, 2>
{
    typedef strategy::transform::rotate_transformer<degree, double, 2, 2> base_t;

    my_rotate_transformer(double angle)
        : base_t(angle)
    {}  

    template <typename P1, typename P2>
    bool apply(P1 const& p1, P2& p2) const
    {
        p2.Set_ID(p1.Get_ID());
        return base_t::apply(p1, p2);
    }
}

类似于std::transform()的使用方式.您必须传递一个UnaryOperation,它可以按照您喜欢的方式转换Range的元素.在Boost.Geometry中,策略用于此目的.

It's similar to the way how std::transform() can be used. You must pass a UnaryOperation which transforms the elements of a Range the way you like it. In Boost.Geometry strategies are used for this purpose.

顺便说一句,这是一种简单的情况,您可以手动复制/设置ID.

Btw, it's a simple case, you could just manually copy/set the IDs.

另一件事是bg::transform()适用于任意几何图形,因此您可以在那里传递多边形(但是您需要为此传递另一个多边形):

Another thing is that bg::transform() works for arbitrary Geometry so you could just pass Polygons there (however you need another Polygon for this):

polygon<My_Point> poly_in;
polygon<My_Point> poly_out;
bg::transform(poly_in, poly_out, my_rotate_transformer(45))

使用append(),您可以将点直接附加到多边形.我认为不需要使用临时std::vector.

Using append() you can directly append Points to Polygon. There is no need to use temporary std::vector, I think.

此外,请记住,某些算法会创建全新的几何图形,其中包含新的点,例如intersection()convex_hull(),因此可能不应该复制ID,或者也不应该复制所有ID.

Also, have in mind that some algorithms creates entirely new Geometries, containing new Points, e.g. intersection() or convex_hull() so IDs probably shouldn't be copied, or not all of them.

最后但并非最不重要的一点是,我猜测某些算法可能会在您的方案中引起问题,这可能取决于算法.因此,随时提出问题.还考虑订阅Boost.Geometry邮件列表.这是与开发人员联系,提出新功能,报告错误等的好地方.

And last but not least, I'm guessing that some algorithms may cause problems in your scenario, it probably depends on the algorithm. So feel free to ask questions. Consider also subscribing to Boost.Geometry mailing list. It's a good place for getting in touch with the developers, proposing new features, reporting bugs, etc.

这篇关于自定义点类中的ID字段间歇性丢失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆