Simple boost polygon boolean OR doesn't work: help needed

Hi, Below is code for doing a boolean OR operation. I'm not sure of the mistake I'm doing here. The output generated is wrong. I'm not using the operator+() becaue of the compile issue on MSVC2010. #include <boost/polygon/polygon.hpp> namespace gtl = boost::polygon; using namespace gtl; using namespace boost::polygon::operators; using namespace std; typedef gtl::polygon_set_data<double> CPolygonSet; typedef gtl::polygon_data<double> CPolygon; static void test_boost_polygons() { CPolygonSet polyset1, polyset2, rset; CPolygon polygon1, polygon2; typedef gtl::polygon_traits<CPolygon>::point_type CPoint; vector<CPoint> poly1Points, poly2Points; poly1Points.push_back(gtl::construct<CPoint>(0.0000, 0.0000)); poly1Points.push_back(gtl::construct<CPoint>(50.0000, 50.0000)); poly1Points.push_back(gtl::construct<CPoint>(100.0000, -50.0000)); poly1Points.push_back(gtl::construct<CPoint>(50.0000, -50.0000)); poly2Points.push_back(gtl::construct<CPoint>(50.0000, 0.0000)); poly2Points.push_back(gtl::construct<CPoint>(100.0000, 50.0000)); poly2Points.push_back(gtl::construct<CPoint>(150.0000, -50.0000)); polygon1.set(poly1Points.begin(), poly1Points.end()); polygon2.set(poly2Points.begin(), poly2Points.end()); vector<CPolygon> polygonArray1, polygonArray2; polygonArray1.push_back(polygon1); polygonArray2.push_back(polygon2); polyset1.insert(polygonArray1.begin(), polygonArray1.end()); polyset2.insert(polygonArray2.begin(), polygonArray2.end()); gtl::arbitrary_boolean_op<CPolygonSet::coordinate_type> bop; bop.execute(rset, polyset1.begin(), polyset1.end(), polyset2.begin(), polyset2.end(), 0); vector<CPolygon> polys; rset.get(polys); for(unsigned int i = 0; i < polys.size(); ++i) { CPolygon::iterator_type it = polys[i].begin(); for(; it != polys[i].end(); ++it) { cout<<"("<<(*it).x()<<", "<<(*it).y()<<")"<<endl; } } } void main() { test_boost_polygons(); } -- -praveen

Praveen Vs wrote:
typedef gtl::polygon_set_data<double> CPolygonSet; typedef gtl::polygon_data<double> CPolygon;
While the coordinate data type is templates, floating point coordinate types are not supported for polygon clipping operations because of the difficulty making the calculations numerically robust. Of the open source polygon clipping libraries I know of only CGAL is numerically robust with floating point coordinates, and it uses multi-precision arithmetic extensively. You need to use integer coordinates. If you don't like the rounding error scale the data to make the rounding error smaller. Your compiler error should hopefully go away with integer coordinate types. I believe my tests are passing on MSVC2010. Regards, Luke

Changing to int doesn't work either. MSVC2010 throws a bunch of compilation errors. Do you use any special compiler flags? or Boost macros? #include <boost/polygon/gtl.hpp> #include <cassert> using namespace std; static void test_boost_polygons() { namespace gtl = boost::polygon; using namespace gtl; using namespace boost::polygon::operators; typedef gtl::polygon_set_data<int> CPolygonSet; typedef gtl::polygon_data<int> CPolygon; CPolygonSet polyset1, polyset2, rset; CPolygon polygon1, polygon2; typedef gtl::polygon_traits<CPolygon>::point_type CPoint; vector<CPoint> poly1Points, poly2Points; poly1Points.push_back(gtl::construct<CPoint>(0, 0)); poly1Points.push_back(gtl::construct<CPoint>(50, 50)); poly1Points.push_back(gtl::construct<CPoint>(100, -50)); poly1Points.push_back(gtl::construct<CPoint>(50, -50)); poly2Points.push_back(gtl::construct<CPoint>(50, 0)); poly2Points.push_back(gtl::construct<CPoint>(100, 50)); poly2Points.push_back(gtl::construct<CPoint>(150, -50)); polygon1.set(poly1Points.begin(), poly1Points.end()); polygon2.set(poly2Points.begin(), poly2Points.end()); vector<CPolygon> polygonArray1, polygonArray2; polygonArray1.push_back(polygon1); polygonArray2.push_back(polygon2); polyset1.insert(polygonArray1.begin(), polygonArray1.end()); polyset2.insert(polygonArray2.begin(), polygonArray2.end()); //rset = polyset1 + polyset2; // this too causes compilation errors! gtl::arbitrary_boolean_op<CPolygonSet::coordinate_type> bop; bop.execute(rset, polyset1.begin(), polyset1.end(), polyset2.begin(), polyset2.end(), 0); vector<CPolygon> polys; rset.get(polys); for(unsigned int i = 0; i < polys.size(); ++i) { CPolygon::iterator_type it = polys[i].begin(); for(; it != polys[i].end(); ++it) { cout<<"("<<(*it).x()<<", "<<(*it).y()<<")"<<endl; } } } On Wed, Feb 8, 2012 at 10:24 PM, Simonson, Lucanus J <lucanus.j.simonson@intel.com> wrote:
Praveen Vs wrote:
typedef gtl::polygon_set_data<double> CPolygonSet; typedef gtl::polygon_data<double> CPolygon;
While the coordinate data type is templates, floating point coordinate types are not supported for polygon clipping operations because of the difficulty making the calculations numerically robust. Of the open source polygon clipping libraries I know of only CGAL is numerically robust with floating point coordinates, and it uses multi-precision arithmetic extensively. You need to use integer coordinates. If you don't like the rounding error scale the data to make the rounding error smaller.
Your compiler error should hopefully go away with integer coordinate types. I believe my tests are passing on MSVC2010.
Regards, Luke
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- -praveen

Praveen Vs wrote:
Changing to int doesn't work either. MSVC2010 throws a bunch of compilation errors. Do you use any special compiler flags? or Boost macros?
Hmm, my tests compile in VC8,9 and 10 for the release branch according to the boost regression tests. http://www.boost.org/development/tests/release/developer/polygon.html I generally don't have to do anything special to compile with MSVC (now that I worked around all the compiler bugs for the older versions). Your code looks very straightforward, and I can't see why it should fail. The operator is exercised in the regression test, so it ought to compile for you. If you send me the compilation errors off list I can read them and tell you what they tell me. Thanks, Luke

Thanks for a reply. Here is my compiler log. I have just pasted the relevant lines: 1>\boost\polygon\polygon_45_set_data.hpp(1458): error C2825: 'iT': must be a class or namespace when followed by '::' 1> \boost\polygon\polygon_45_set_data.hpp(1524) : see reference to function template instantiation 'void boost::polygon::get_error_rects_shell<cT,const boost::polygon::point_data<T>*>(cT &,cT &,iT,iT)' being compiled 1> with 1> [ 1> cT=stlp_std::vector<boost::polygon::rectangle_data<Unit2>>, 1> T=Unit2, 1> iT=const boost::polygon::point_data<Unit2> 1> ] 1> \boost\polygon\polygon_45_set_data.hpp(1731) : see reference to function template instantiation 'void boost::polygon::get_error_rects<stlp_std::vector<_Tp>,boost::polygon::polygon_45_with_holes_data<T>>(cT &,cT &,const pT &)' being compiled 1> with 1> [ 1> _Tp=boost::polygon::rectangle_data<Unit2>, 1> T=Unit2, 1> cT=stlp_std::vector<boost::polygon::rectangle_data<Unit2>>, 1> pT=boost::polygon::polygon_45_with_holes_data<Unit2> 1> ] On Thu, Feb 9, 2012 at 9:42 AM, Simonson, Lucanus J <lucanus.j.simonson@intel.com> wrote:
Praveen Vs wrote:
Changing to int doesn't work either. MSVC2010 throws a bunch of compilation errors. Do you use any special compiler flags? or Boost macros?
Hmm, my tests compile in VC8,9 and 10 for the release branch according to the boost regression tests.
http://www.boost.org/development/tests/release/developer/polygon.html
I generally don't have to do anything special to compile with MSVC (now that I worked around all the compiler bugs for the older versions).
Your code looks very straightforward, and I can't see why it should fail. The operator is exercised in the regression test, so it ought to compile for you. If you send me the compilation errors off list I can read them and tell you what they tell me.
Thanks, Luke
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- -praveen

The error: 1>\boost\polygon\polygon_45_set_data.hpp(1458): error C2825: 'iT': must be a class or namespace when followed by '::' 1> \boost\polygon\polygon_45_set_data.hpp(1524) : see reference to function template instantiation 'void boost::polygon::get_error_rects_shell<cT,const boost::polygon::point_data<T>*>(cT &,cT &,iT,iT)' My code: template <typename cT, typename iT> void get_error_rects_shell(cT& posE, cT& negE, iT beginr, iT endr) { typedef typename iT::value_type Point; The problem is that the iterator is pointer type, and I should have used iterator_traits rather than trying to directly access the member typedef value_type. Are you compiling with C++11 version of stl? This should never work for pointer type, yet my tests pass. It must be the case that every version of the stl that I've tested with implements vector iterator as class type while yours is using pointer type. Even though I know better, it is hard to catch these kinds of mistakes when tests pass. The fix is to change iT::value_type to std::iterator_traits<iT>::value_type in line 1458, which you can apply locally. Assuming that is your only error it should allow you to compile, but I would guess that selecting a different (older?) version of the stl would also work. Thanks, Luke

Yes doing that worked. I use the stl 5.2.1 Thanks, On Thu, Feb 9, 2012 at 10:28 AM, Simonson, Lucanus J <lucanus.j.simonson@intel.com> wrote:
The error:
1>\boost\polygon\polygon_45_set_data.hpp(1458): error C2825: 'iT': must be a class or namespace when followed by '::' 1> \boost\polygon\polygon_45_set_data.hpp(1524) : see reference to function template instantiation 'void boost::polygon::get_error_rects_shell<cT,const boost::polygon::point_data<T>*>(cT &,cT &,iT,iT)'
My code:
template <typename cT, typename iT> void get_error_rects_shell(cT& posE, cT& negE, iT beginr, iT endr) { typedef typename iT::value_type Point;
The problem is that the iterator is pointer type, and I should have used iterator_traits rather than trying to directly access the member typedef value_type. Are you compiling with C++11 version of stl? This should never work for pointer type, yet my tests pass. It must be the case that every version of the stl that I've tested with implements vector iterator as class type while yours is using pointer type. Even though I know better, it is hard to catch these kinds of mistakes when tests pass.
The fix is to change iT::value_type to std::iterator_traits<iT>::value_type in line 1458, which you can apply locally. Assuming that is your only error it should allow you to compile, but I would guess that selecting a different (older?) version of the stl would also work.
Thanks, Luke
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- -praveen
participants (2)
-
Praveen Vs
-
Simonson, Lucanus J