jmahony
jmahony

Reputation: 166

C++ Comparator Not Working

I'm trying to sort a set of OpenSG points by their x coord within a set, but it doesn't seem to be working.

My comparator:

struct less_than_x {
    inline bool operator() (const OSG::Pnt3f& p1, const OSG::Pnt3f& p2) {
        return (p1.x() < p2.x());
    }
};

My code:

std::set<OSG::Pnt3f, less_than_x> positions3D; 

OSG::GeoPnt3fPropertyRefPtr pos = OSG::GeoPnt3fProperty::create();

pos->addValue(OSG::Pnt3f(1,2,3));
pos->addValue(OSG::Pnt3f(5,2,1));
pos->addValue(OSG::Pnt3f(4,4,2));
pos->addValue(OSG::Pnt3f(6,4,0));
pos->addValue(OSG::Pnt3f(3,5,1));

// Remove the Z Axis from all of the points
for(OSG::UInt32 i = 0; i < pos->size(); i++)    {        
    OSG::Pnt3f p;              
    pos->getValue(p,i);
    OSG::Pnt3f p2 = OSG::Pnt3f(p.x(), p.y(), 0);
    positions3D.insert(p2);
}

for (std::set<OSG::Pnt3f>::iterator it = positions3D.begin(); it != positions3D.end(); it++) {
    std::cout << *it << std::endl;
}

When printing out the set of points, they are still not in order.

Any help would be greatly appreciated.

Edit:

vershov answer seems to work somwhat for me, but when changing it to double and using this set of points it fails.

positions3D.insert(Pnt3f(-1, 0, 0));
positions3D.insert(Pnt3f(-0.850651, -0.309017, 0));
positions3D.insert(Pnt3f(-0.850651, 0, 0));
positions3D.insert(Pnt3f(-0.525731, 0, 0));
positions3D.insert(Pnt3f(-0.525731, 0.809017, 0));
positions3D.insert(Pnt3f(-0.525731, 0.5, 0));
positions3D.insert(Pnt3f(-0.447214, 0.525731, 0));
positions3D.insert(Pnt3f(-0.447214, 0.850651, 0));
positions3D.insert(Pnt3f(-0.447214, 0, 0));
positions3D.insert(Pnt3f(-1.05104e-007, 0.309017, 0));
positions3D.insert(Pnt3f(-7.00695e-008, 0.809017, 0));
positions3D.insert(Pnt3f(0, 1, 0));
positions3D.insert(Pnt3f(7.00695e-008, 0.809017, 0));
positions3D.insert(Pnt3f(1.05104e-007, -0.309017, 0));
positions3D.insert(Pnt3f(0.447214, 0, 0));
positions3D.insert(Pnt3f(0.447214, 0.850651, 0));
positions3D.insert(Pnt3f(0.447214, 0.525731, 0));
positions3D.insert(Pnt3f(0.525731, 0.5, 0));
positions3D.insert(Pnt3f(0.525731, 0.809017, 0));
positions3D.insert(Pnt3f(0.525731, 0, 0));
positions3D.insert(Pnt3f(0.850651, 0, 0));
positions3D.insert(Pnt3f(0.850651, 0.5, 0));
positions3D.insert(Pnt3f(1, 0, 0));

These are sorted in this order:

-1, 0, 0
-0.850651, -0.309017, 0
-0.850651, 0, 0
-0.525731, 0, 0
-0.525731, 0.809017, 0
-0.525731, 0.5, 0
-0.447214, 0.525731, 0
-0.447214, 0.850651, 0
-0.447214, 0, 0
-1.05104e-007, 0.309017, 0
-7.00695e-008, 0.809017, 0
0, 1, 0
7.00695e-008, 0.809017, 0
1.05104e-007, -0.309017, 0
0.447214, 0, 0
0.447214, 0.850651, 0
0.447214, 0.525731, 0
0.525731, 0.5, 0
0.525731, 0.809017, 0
0.525731, 0, 0
0.850651, 0, 0
0.850651, 0.5, 0
1, 0, 0    

Upvotes: 0

Views: 366

Answers (1)

vershov
vershov

Reputation: 928

Please check the following code:

#include <set>
#include <iostream>

struct Pnt3f {
        Pnt3f(int x, int y, int z) : m_x(x), m_y(y), m_z(z) {}
        int x() const { return m_x; }
        int y() const { return m_y; }
        int z() const { return m_z; }
private:
        int m_x;
        int m_y;
        int m_z;
};

struct less_than_x {
    inline bool operator() (const Pnt3f& p1, const Pnt3f& p2) {
        return (p1.x() < p2.x());
    }
};

int main() {

        std::set<Pnt3f, less_than_x> positions3D;

        positions3D.insert(Pnt3f(1,2,0));
        positions3D.insert(Pnt3f(5,2,0));
        positions3D.insert(Pnt3f(4,4,0));
        positions3D.insert(Pnt3f(6,4,0));
        positions3D.insert(Pnt3f(3,5,0));

        for (std::set<Pnt3f>::iterator it = positions3D.begin(); it != positions3D.end(); ++it) {
                std::cout << "(" << it->x() << ", " << it->y() << ", " << it->z() << ")" << std::endl;
        }
        return 0;
}

The output is as following:

./a.out 
(1, 2, 0)
(3, 5, 0)
(4, 4, 0)
(5, 2, 0)
(6, 4, 0)

So, comparator works as expected and do sort. You need to print out values before line to understand what is going wrong.

positions3D.insert(p2);

Upvotes: 1

Related Questions