Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

polygon_data_set::insert creates unwanted polygon point #52

Open
todeschini-felipe opened this issue Sep 11, 2020 · 1 comment
Open

Comments

@todeschini-felipe
Copy link

todeschini-felipe commented Sep 11, 2020

I want to represent a donut shape with boost::polygon, such as the figure below, with the following points:
image

10 polygon : (0, 0), (10, 0), (10, 10), (8, 10), (8, 2), (2, 2), (2, 8), (8, 8), (8, 10), (0, 10),

Once I include the polygon into a polygon set data, however, it creates an additional unwanted point (8,8) from (8,10)->(8,2). Even boost::polygon::simplify leaves this point. Is that the expected behavior?

12 insert : (10, 10), (8, 10), (8, 8), (8, 2), (2, 2), (2, 8), (8, 8), (8, 10), (0, 10), (0, 0), (10, 0), (10, 10),
12 simplf : (10, 10), (8, 10), (8, 8), (8, 2), (2, 2), (2, 8), (8, 8), (8, 10), (0, 10), (0, 0), (10, 0), (10, 10), 
#include <iostream>

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/linestring.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/polygon/polygon.hpp>

#include <boost/assign.hpp>

using namespace boost::assign;
namespace gtl = boost::polygon;
using namespace boost::polygon::operators;

//--------------------------------------------------------------------------------
// CPoint
//--------------------------------------------------------------------------------
struct CPoint {
  //CPoint() : x(0), y(0) {}
  //CPoint(int a, int b) : x(a), y(b) {}

  int x;
  int y;
};

namespace boost::polygon {
template <>
struct geometry_concept<CPoint> { typedef point_concept type; };
template <>
struct point_traits<CPoint> {
  typedef int coordinate_type;

  static inline coordinate_type get(const CPoint& point, orientation_2d orient) {
    return ((orient == HORIZONTAL) ? point.x : point.y);
  }
};

template <>
struct point_mutable_traits<CPoint> {
  typedef int coordinate_type;

  static inline void set(CPoint& point, orientation_2d orient, int value) {
    if(orient == HORIZONTAL)
      point.x = value;
    else
      point.y = value;
  }
  static inline CPoint construct(int x_value, int y_value) {
    CPoint retval;
    retval.x = x_value;
    retval.y = y_value;
    return retval;
  }
};
}

//--------------------------------------------------------------------------------
// CPolygon
//--------------------------------------------------------------------------------
typedef std::list<CPoint> CPolygon;

namespace boost::polygon {
template <>
struct geometry_concept<CPolygon>{ typedef polygon_concept type; };

template <>
struct polygon_traits<CPolygon> {
  typedef int coordinate_type;
  typedef CPolygon::const_iterator iterator_type;
  typedef CPoint point_type;

  static inline iterator_type begin_points(const CPolygon& t) { return t.begin(); }
  static inline iterator_type end_points(const CPolygon& t) { return t.end(); }
  static inline std::size_t size(const CPolygon& t) { return t.size(); }
  static inline winding_direction winding(const CPolygon& t) { return unknown_winding; }
};

template <>
struct polygon_mutable_traits<CPolygon> {
  template <typename iT>
  static inline CPolygon& set_points(CPolygon& t, iT input_begin, iT input_end) {
    t.clear();
    while(input_begin != input_end) {
      t.push_back(CPoint());
      gtl::assign(t.back(), *input_begin);
      ++input_begin;
    }
    return t;
  }
};
}

std::ostream &operator<<(std::ostream &os, const CPoint &p) {
  return os << "(" << p.x << ", " << p.y << ")";
}

std::ostream &operator<<(std::ostream &os, const CPolygon &p) {
  for (const auto point : p)
    os << point << ", ";
  return os;
}


int main()
{
  CPolygon donut{
    CPoint{0, 0}, CPoint{10,0}, CPoint{10, 10},
    CPoint{8, 10}, CPoint{8, 2},
    CPoint{2, 2}, CPoint{2, 8}, CPoint{8, 8},
   CPoint{8,10}, CPoint{0,10} }; 

  std::cout << donut.size() << "  donut : " << donut << std::endl;

  boost::polygon::polygon_set_data<int> ps;
  std::vector<CPolygon> polygons;
  ps.insert(donut);
  ps.get(polygons);
  for (const auto &pl : polygons)
    std::cout << pl.size() << " insert : " << pl << std::endl;

  polygons.clear();
  boost::polygon::simplify(ps, 1e-3);
  ps.get(polygons);
  for (const auto &pl : polygons)
    std::cout << pl.size() << " simplf : " << pl << std::endl;

	return 0;
}

@todeschini-felipe todeschini-felipe changed the title polygon_set_data creates undesirable/redudant point during insertion delete this Sep 11, 2020
@todeschini-felipe todeschini-felipe changed the title delete this polygon_data_set::insert creates unwanted polygon point Sep 11, 2020
@by408
Copy link

by408 commented Jan 29, 2021

ps.get(polygons); function applies a union operation to the polygons. This is by definition. If you add overlapping polygons and call get function you will get merged results, it won't match your original input.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants