Limbo
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Polygon2Rectangle.h
Go to the documentation of this file.
1 
13 #ifndef _LIMBO_GEOMETRY_POLYGON2RECTANGLE
14 #define _LIMBO_GEOMETRY_POLYGON2RECTANGLE
15 
16 #include <iostream>
17 #include <fstream>
18 #include <string>
19 #include <vector>
20 #include <list>
21 #include <map>
22 #include <boost/lexical_cast.hpp>
23 #include <boost/algorithm/string/trim.hpp>
24 #include <boost/algorithm/string/classification.hpp>
26 #include <limbo/string/String.h>
28 
30 namespace limbo
31 {
33 namespace geometry
34 {
35 
36 using std::cout;
37 using std::endl;
38 using std::ifstream;
39 using std::ofstream;
40 using std::string;
41 using std::vector;
42 using std::map;
43 
51 {
53 
62  point_compare_type(orientation_2d const& ori) : m_orient(ori) {}
63 
71  template <typename PointType>
72  inline bool operator()(PointType const& p1, PointType const& p2) const
73  {
74  assert(m_orient.valid());
75  return point_traits<PointType>::get(p1, m_orient) < point_traits<PointType>::get(p2, m_orient)
76  || (point_traits<PointType>::get(p1, m_orient) == point_traits<PointType>::get(p2, m_orient)
78  );
79  }
80 };
81 
88 template <typename PointSet,
89  typename RectSet>
91 {
92  public:
94  typedef RectSet rectangle_set_type;
96  typedef PointSet point_set_type;
98  typedef typename container_traits<point_set_type>::value_type point_type;
100  typedef typename point_traits<point_type>::coordinate_type coordinate_type;
102  typedef typename container_traits<rectangle_set_type>::value_type rectangle_type;
107 
118  Polygon2Rectangle(rectangle_set_type& vRect, slicing_orientation_2d slicing_orient = HORIZONTAL_SLICING)
119  : m_mPoint()
120  , m_vRect(vRect)
121  , m_slicing_orient(slicing_orient)
122  {
123  this->initialize(slicing_orient);
124  }
133  template <typename InputIterator>
134  Polygon2Rectangle(rectangle_set_type& vRect, InputIterator input_begin, InputIterator input_end, slicing_orientation_2d slicing_orient)
135  : m_mPoint()
136  , m_vRect(vRect)
137  , m_slicing_orient(slicing_orient)
138  {
139  this->initialize(slicing_orient);
140  this->initialize(input_begin, input_end);
141  }
148  template <typename InputIterator>
149  void initialize(InputIterator input_begin, InputIterator input_end)
150  {
151  // 1. collecting vertices from input container
152  // it should be ordered, clockwise or counterclockwise
153  // identical vertices are skipped
154  // extra vertices in the same line are skipped
155  std::vector<point_type> vTmpPoint;
156  // I'm trying to use only forward_iteartor, which only supports ++ operation
157  // so it may spend more effort on getting the last point
158  InputIterator input_last = input_end;
159  for (InputIterator itCur = input_begin; itCur != input_end; ++itCur)
160  {
161  InputIterator itNext = itCur;
162  ++itNext;
163  if (itNext == input_end)
164  {
165  input_last = itCur;
166  break;
167  }
168  }
169  assert_msg(input_last != input_end, "failed to find input_last, maybe too few points");
170  if (is_equal_type()(*input_begin, *input_last)) ++input_begin; // skip identical first and last points
171  // use only operator++ so that just forward_iteartor is enough
172  for (InputIterator itPrev = input_begin; itPrev != input_end; ++itPrev)
173  {
174  InputIterator itCur = itPrev;
175  ++itCur;
176  if (itCur == input_end)
177  itCur = input_begin;
178  InputIterator itNext = itCur;
179  ++itNext;
180  if (itNext == input_end)
181  itNext = input_begin;
182 
183  // skip identical vertices
184  if (is_equal_type()(*itCur, *itNext))
185  continue;
186 
187  // skip extra vertices in the same line
188  if (this->get(*itPrev, HORIZONTAL) == this->get(*itCur, HORIZONTAL)
189  && this->get(*itCur, HORIZONTAL) == this->get(*itNext, HORIZONTAL)) // vertical line
190  {
191 #ifdef DEBUG
192  assert(std::min(this->get(*itPrev, VERTICAL), this->get(*itNext, VERTICAL)) <= this->get(*itCur, VERTICAL)
193  && std::max(this->get(*itPrev, VERTICAL), this->get(*itNext, VERTICAL)) >= this->get(*itCur, VERTICAL));
194 #endif
195  continue;
196  }
197  else if (this->get(*itPrev, VERTICAL) == this->get(*itCur, VERTICAL)
198  && this->get(*itCur, VERTICAL) == this->get(*itNext, VERTICAL)) // horizontal line
199  {
200 #ifdef DEBUG
201  assert(std::min(this->get(*itPrev, HORIZONTAL), this->get(*itNext, HORIZONTAL)) <= this->get(*itCur, HORIZONTAL)
202  && std::max(this->get(*itPrev, HORIZONTAL), this->get(*itNext, HORIZONTAL)) >= this->get(*itCur, HORIZONTAL));
203 #endif
204  continue;
205  }
206 
207  // consider edge from itCur to itNext:
209  vTmpPoint,
211  this->get(*itCur, HORIZONTAL),
212  this->get(*itCur, VERTICAL)
213  ));
214  }
215 #ifdef DEBUG
216  // a simple manhattan polygon should have even number of different points
217  assert(vTmpPoint.size() % 2 == 0);
218 #endif
219 
220  // copy from vTmpPoint to m_mPoint
221  for (typename map<orientation_2d, point_set_type>::iterator it = m_mPoint.begin();
222  it != m_mPoint.end(); ++it)
223  {
224  orientation_2d const& orient = it->first;
225  point_set_type& vPoint = it->second;
226 
227  std::sort(vTmpPoint.begin(), vTmpPoint.end(), point_compare_type(orient));
228  // remove points that appear more than once
229  // in other words, after following operation, contour polygon will become polygon with holes
230  vPoint.clear();
231  //vPoint.reserve(vTmpPoint.size()); // not defined in containers like set
232  for (typename vector<point_type>::iterator itCur = vTmpPoint.begin(); itCur != vTmpPoint.end(); ++itCur)
233  {
234  typename vector<point_type>::iterator itNext = itCur;
235  ++itNext;
236  if (itNext == vTmpPoint.end())
237  itNext = vTmpPoint.begin();
238  if (!is_equal_type()(*itCur, *itNext))
239  container_traits<point_set_type>::insert(vPoint, vPoint.end(), *itCur); // provide hint for insertion
240  else
241  {
242  ++itCur;
243  if (itCur == vTmpPoint.end()) break;
244  }
245  }
246  }
247 #ifdef DEBUG
248  cout << "reduce from " << vTmpPoint.size() << " to " << m_mPoint.begin()->second.size() << endl;
249 #endif
250  }
251 
256  bool operator()()
257  {
258 #ifdef _DEBUG_PTR
259  std::cout << "debug| PTR::Polygon2Rectangle(), m_vPoint = " << std::endl;
260  print("debug.gp");
261 #endif
262 
263  vector<rectangle_type> vRect (m_mPoint.size());
264 
265  while (m_mPoint.begin()->second.size() > 0)
266  {
267  int i = 0;
268 
269  for (typename map<orientation_2d, point_set_type>::iterator it = m_mPoint.begin();
270  it != m_mPoint.end(); ++it, ++i)
271  {
272  orientation_2d const& orient = it->first;
273 #ifdef DEBUG
274  point_set_type const& vPoint = it->second; // just for gdb
275  assert(vPoint.empty() || !vPoint.empty()); // to remove annoying warning
276 #endif
277 
278  point_type Pk, Pl, Pm;
279 
280  if (!this->find_Pk_Pl_Pm(Pk, Pl, Pm, orient))
281  return false;
282 
283  rectangle_type& rect = vRect[i];
284 
285  // it is safer to do it with construct because some rectangle classes may not support setting borders one-by-one
286  // for HORIZONTAL_SLICING, sort by VERTICAL, Pm decides TOP, Pl decides RIGHT
287  // for VERTICAL_SLICING, sort by HORIZONTAL, Pl decides TOP, Pm decides RIGHT
289  this->get(Pk, HORIZONTAL),
290  this->get(Pk, VERTICAL),
291  std::max(this->get(Pl, HORIZONTAL), this->get(Pm, HORIZONTAL)),
292  std::max(this->get(Pl, VERTICAL), this->get(Pm, VERTICAL)));
293 #ifdef DEBUG
294  // check rectangle
295  if (this->get(rect, RIGHT) > std::numeric_limits<coordinate_type>::max()-1000
296  || this->get(rect, TOP) > std::numeric_limits<coordinate_type>::max()-1000)
297  return false;
298 #endif
299  }
300  // choose rectangle
301  typename vector<rectangle_type>::iterator itRect = vRect.begin();
302  for (typename vector<rectangle_type>::iterator it = ++vRect.begin(); it != vRect.end(); ++it)
303  {
304  // it is possible to try different strategies here
305  // choose the one with heuristic
306  coordinate_distance w = this->get(*it, RIGHT)-this->get(*it, LEFT);
307  coordinate_distance h = this->get(*it, TOP)-this->get(*it, BOTTOM);
308  coordinate_distance wref = this->get(*itRect, RIGHT)-this->get(*itRect, LEFT);
309  coordinate_distance href = this->get(*itRect, TOP)-this->get(*itRect, BOTTOM);
310  switch (m_slicing_orient)
311  {
312  case HOR_VER_SLICING:
313  {
314  // compute area
315  if (w*h > wref*href) // choose large area
316  itRect = it;
317  break;
318  }
319  case HOR_VER_SA_SLICING:
320  {
321  // compute area
322  if (w*h < wref*href) // choose small area
323  itRect = it;
324  break;
325  }
326  case HOR_VER_AR_SLICING:
327  {
328  // compute aspect ratio = maxDelta/minDelta
329  coordinate_distance minDelta = w;
330  coordinate_distance maxDelta = h;
331  coordinate_distance minDeltaRef = wref;
332  coordinate_distance maxDeltaRef = href;
333  if (minDelta > maxDelta)
334  std::swap(minDelta, maxDelta);
335  if (minDeltaRef > maxDeltaRef)
336  std::swap(minDeltaRef, maxDeltaRef);
337  // I rearrage the aspect ratio computation to avoid division
338  if (maxDelta*minDeltaRef < minDelta*maxDeltaRef) // avoid rectangle with bad aspect ratio
339  itRect = it;
340  break;
341  }
342  default:
343  assert_msg(0, "should not reach here " << m_slicing_orient);
344  }
345  }
346  // insert or remove point
347  for (typename map<orientation_2d, point_set_type>::iterator it = m_mPoint.begin();
348  it != m_mPoint.end(); ++it)
349  {
350  orientation_2d const& orient = it->first;
351 #ifdef DEBUG
352  point_set_type const& vPoint = it->second; // just for gdb
353  assert(vPoint.empty() || !vPoint.empty()); // to remove annoying warning
354 #endif
355 
356  F(point_traits<point_type>::construct(this->get(*itRect, LEFT), this->get(*itRect, BOTTOM)), orient);
357  F(point_traits<point_type>::construct(this->get(*itRect, LEFT), this->get(*itRect, TOP)), orient);
358  F(point_traits<point_type>::construct(this->get(*itRect, RIGHT), this->get(*itRect, BOTTOM)), orient);
359  F(point_traits<point_type>::construct(this->get(*itRect, RIGHT), this->get(*itRect, TOP)), orient);
360  }
361  // collect rectangle
363  }
364 
365  return true;
366  }
371  rectangle_set_type const& get_rectangles() const
372  {
373  return m_vRect;
374  }
380  bool read(string const& filename)
381  {
382  ifstream in (filename.c_str());
383  if (!in.good())
384  {
385  cout << "failed to open " << filename << endl;
386  return false;
387  }
388 
389  string tag;
390  string value_str;
391  int status = 0; // status records line number
392  // if status > 0, it means in a polygon scope
393  std::vector<point_type> vPoint; // temporary point set
394 
395  while (!in.eof())
396  {
397  in >> tag;
398  if (tag == "polygon" && status == 0)
399  {
400  status = 1;
401  }
402  else if (tag == "from" || tag == "to")
403  {
404  int i = 0;
405  coordinate_type value[2] = {0, 0};
406  // read until get two numbers
407  // there may be some delimiters like ',' '\'
408  while (!in.eof() && i < 2)
409  {
410  in >> value_str;
411  boost::trim_if(value_str, boost::is_any_of(", \t\\"));
412  if (::limbo::is_number(value_str))
413  {
414  value[i] = boost::lexical_cast<coordinate_type>(value_str);
415  // increment i if value_str represents a number
416  i += 1;
417  }
418  }
419  // return false if reading failed
420  if (i != 2) return false;
421  // add current point to point set
422  vPoint.push_back(point_type());
423  this->set(vPoint.back(), HORIZONTAL, value[0]);
424  this->set(vPoint.back(), VERTICAL, value[1]);
425  }
426  else if (status == 1)
427  {
428  status = 0;
429  break; // only read one polygon
430  }
431  }
432  // after reading, call initialize function
433  this->initialize(vPoint.begin(), vPoint.end());
434 
435  return true;
436  }
441  void print(string const& filename) const
442  {
443  ofstream out (filename.c_str());
444  if (!out.good())
445  {
446  cout << "failed to open " << filename << endl;
447  return;
448  }
449  int i = 1; // gnuplot requires numbering from 1
450  point_set_type const& vPoint = m_mPoint.begin()->second;
451  // print current polygon if exists
452  if (vPoint.size() > 0)
453  {
454  out << "set obj " << i++ << " ";
455  out << "polygon \\" << endl;
456  for (typename point_set_type::const_iterator it = vPoint.begin(); it != vPoint.end(); ++it)
457  {
458  if (it == vPoint.begin())
459  out << "from " << this->get(*it, HORIZONTAL) << ", " << this->get(*it, VERTICAL) << " \\" << endl;
460  else
461  out << "to " << this->get(*it, HORIZONTAL) << ", " << this->get(*it, VERTICAL) << " \\" << endl;
462  }
463  out << endl;
464  }
465 
466  // print rectangles
467  for (typename rectangle_set_type::const_iterator it = m_vRect.begin(); it != m_vRect.end(); ++it)
468  {
469  // print rectangle
470  out << "set obj " << i << " rectangle ";
471  out << "from " << this->get(*it, LEFT) << ", " << this->get(*it, BOTTOM) << " "
472  << "to " << this->get(*it, RIGHT) << ", " << this->get(*it, TOP) << " ";
473  out << "fc rgb \"dark-grey\" fs transparent pattern 4 bo"<< endl;
474  // print text on the center of rectangle
475  out << "set label \'" << i << "\' at "
476  << (this->get(*it, LEFT)+this->get(*it, RIGHT))/2.0 << ", " << (this->get(*it, BOTTOM)+this->get(*it, TOP))/2.0 << " "
477  << "front center tc rgb \"black\"" << endl;
478  ++i;
479  }
480  }
481 
482  protected:
489  inline coordinate_type get(point_type const& p, orientation_2d o) const {return point_traits<point_type>::get(p, o);}
496  inline coordinate_type get(rectangle_type const& r, direction_2d d) const {return rectangle_traits<rectangle_type>::get(r, d);}
503  inline void set(point_type& p, orientation_2d o, coordinate_type v) const {point_traits<point_type>::set(p, o, v);}
510  inline void set(rectangle_type& r, direction_2d d, coordinate_type v) const {rectangle_traits<rectangle_type>::set(r, d, v);}
511 
516  {
523  inline bool operator() (point_type const& p1, point_type const& p2) const
524  {
525  return point_traits<point_type>::get(p1, HORIZONTAL) == point_traits<point_type>::get(p2, HORIZONTAL)
526  && point_traits<point_type>::get(p1, VERTICAL) == point_traits<point_type>::get(p2, VERTICAL);
527  }
528  };
534  void initialize(slicing_orientation_2d slicing_orient)
535  {
536  switch (slicing_orient)
537  {
538  case HORIZONTAL_SLICING:
539  assert(m_mPoint.insert(make_pair(
540  VERTICAL,
542  )).second);
543  break;
544  case VERTICAL_SLICING:
545  assert(m_mPoint.insert(make_pair(
546  HORIZONTAL,
548  )).second);
549  break;
550  case HOR_VER_SLICING:
551  case HOR_VER_SA_SLICING:
552  case HOR_VER_AR_SLICING:
553  assert(m_mPoint.insert(make_pair(
554  VERTICAL,
556  )).second);
557  assert(m_mPoint.insert(make_pair(
558  HORIZONTAL,
560  )).second);
561  break;
562  default:
563  cout << "unknown slicing orientation" << endl;
564  assert(0);
565  }
566  }
576  bool find_Pk_Pl_Pm(point_type& Pk, point_type& Pl, point_type& Pm, orientation_2d const& orient)
577  {
578  point_set_type const& vPoint = m_mPoint[orient];
579  if (vPoint.size() < 4)
580  return false;
581 
582  // always keep it sorted
583  // copy first point to Pk
584  this->set(Pk, HORIZONTAL, this->get(*vPoint.begin(), HORIZONTAL));
585  this->set(Pk, VERTICAL, this->get(*vPoint.begin(), VERTICAL));
586  // copy second point to Pl
587  this->set(Pl, HORIZONTAL, this->get(*(++(vPoint.begin())), HORIZONTAL));
588  this->set(Pl, VERTICAL, this->get(*(++(vPoint.begin())), VERTICAL));
589  // determine Pm
590  this->set(Pm, HORIZONTAL, std::numeric_limits<coordinate_type>::max());
591  this->set(Pm, VERTICAL, std::numeric_limits<coordinate_type>::max());
592  for (typename point_set_type::const_iterator it = vPoint.begin(); it != vPoint.end(); ++it)
593  {
594  if (this->get(Pk, orient) == this->get(*it, orient))
595  continue;
596  else if (this->get(Pk, orient.get_perpendicular()) <= this->get(*it, orient.get_perpendicular())
597  && this->get(*it, orient.get_perpendicular()) <= this->get(Pl, orient.get_perpendicular()))
598  {
599  assert(this->get(*it, orient) > this->get(Pk, orient));
600  this->set(Pm, HORIZONTAL, this->get(*it, HORIZONTAL));
601  this->set(Pm, VERTICAL, this->get(*it, VERTICAL));
602  break;
603  }
604  }
605  if (this->get(Pm, HORIZONTAL) == std::numeric_limits<coordinate_type>::max()
606  || this->get(Pm, VERTICAL) == std::numeric_limits<coordinate_type>::max())
607  return false;
608 
609  return true;
610  }
617  void F(point_type const& point, orientation_2d const& orient)
618  {
619  point_set_type& vPoint = m_mPoint[orient];
620 
621  // vPoint is always in order
622  typename point_set_type::iterator itr = std::lower_bound(vPoint.begin(), vPoint.end(), point, point_compare_type(orient));
623 
624  if (itr == vPoint.end() || !is_equal_type()(*itr, point)) // not found, insert point
625  {
626  container_traits<point_set_type>::insert(vPoint, itr, point);
627  }
628  else // found, remove point
629  {
631  }
632  }
633 #if 0
634  coordinate_type getHorRangeNext(coordinate_type const& x1, coordinate_type const& x2, coordinate_type const& min_y) const
636  {
637  coordinate_type next_y = std::numeric_limits<coordinate_type>::max() / 2;
638 
639  for (typename point_set_type::const_iterator it = m_vPoint.begin(); it != m_vPoint.end(); ++it)
640  {
641  coordinate_type x = this->get(*it, HORIZONTAL), y = this->get(*it, VERTICAL);
642  if (x<x1 || x>x2) continue;
643  if (y <= min_y) continue;
644  if (y >= next_y) continue;
645 
646  next_y = y;
647  }
648 
649  return next_y;
650  }
651 
652  coordinate_type getVerRangeNext(coordinate_type const& y1, coordinate_type const& y2, coordinate_type const& min_x) const
653  {
654  coordinate_type next_x = std::numeric_limits<coordinate_type>::max() / 2;
655 
656  for (typename point_set_type::const_iterator it = m_vPoint.begin(); it != m_vPoint.end(); ++it)
657  {
658  coordinate_type x = this->get(*it, HORIZONTAL), y = this->get(*it, VERTICAL);
659  if (y<y1 || y>y2) continue;
660  if (x <= min_x) continue;
661  if (x >= next_x) continue;
662 
663  next_x = x;
664  }
665 
666  return next_x;
667  }
668 #endif
669  map<orientation_2d, point_set_type> m_mPoint;
670  rectangle_set_type& m_vRect;
675 };
676 
677 } // namespace geometry
678 } // namespace limbo
679 
680 // a specialization for vectors
682 
683 namespace limbo
684 {
685 namespace geometry
686 {
687 
697 template <typename InputIterator, typename PointSet, typename RectSet>
698 inline bool polygon2rectangle(InputIterator input_begin, InputIterator input_end,
699  PointSet const&, RectSet& r, slicing_orientation_2d slicing_orient = HORIZONTAL_SLICING)
700 {
701  Polygon2Rectangle<PointSet, RectSet> p2r (r, input_begin, input_end, slicing_orient);
702  if (!p2r()) return false;
703  return true;
704 }
705 
706 } // namespace geometry
707 } // namespace limbo
708 
709 #endif
static rectangle_type construct(coordinate_type const &xl, coordinate_type const &yl, coordinate_type const &xh, coordinate_type const &yh)
construct rectangle from coordinates
Definition: Geometry.h:221
static coordinate_type get(const point_type &point, orientation_2d const &orient)
get coordinate from point
Definition: Geometry.h:179
static void set(rectangle_type &rectangle, direction_2d const &direct, coordinate_type const &v)
set coordinate for rectangle
Definition: Geometry.h:216
bool valid() const
check whether the orientation is valid
Definition: Geometry.h:132
void set(rectangle_type &r, direction_2d d, coordinate_type v) const
set coordinate of rectangle
rectangle_set_type const & get_rectangles() const
get rectangles
map< orientation_2d, point_set_type > m_mPoint
void initialize(slicing_orientation_2d slicing_orient)
initialize with slicing orientation it must be called before initializing other data ...
static void set(point_type &point, orientation_2d const &orient, coordinate_type const &value)
set coordinate for point
Definition: Geometry.h:185
direction_2d
direction type for rectangles
Definition: Geometry.h:72
horizontal/vertical slicing and choose rectangle with smaller area every time
Definition: Geometry.h:44
sort helper if orient == HORIZONTAL, sort by left lower if orient == VERTICAL, sort by lower left ...
slicing_orientation_2d m_slicing_orient
slicing orient
Contains utilities for geometric types, such as type traits, area calculator. I'm trying to make thes...
assertion with message
PointSet point_set_type
internal point set type
slicing_orientation_2d
orientation type for slicing
Definition: Geometry.h:39
bool read(string const &filename)
read polygon from file try to be compatible to gnuplot format
void set(point_type &p, orientation_2d o, coordinate_type v) const
set coordinate of point
type traits for containers such as vector, list, multiset
Definition: Geometry.h:254
coordinate_traits< coordinate_type >::coordinate_distance coordinate_distance
coordinate distance type
bool find_Pk_Pl_Pm(point_type &Pk, point_type &Pl, point_type &Pm, orientation_2d const &orient)
find Pk, Pl, Pm, please refer to the paper for definition Given points, find Pk, Pl and Pm ...
a class implement conversion from manhattan polygon to rectangle
bool is_number(string const &s)
check whether string represents a number, either integer or floating point number ...
Definition: String.h:62
Polygon2Rectangle(rectangle_set_type &vRect, slicing_orientation_2d slicing_orient=HORIZONTAL_SLICING)
constructor
static coordinate_type get(rectangle_type const &rectangle, direction_2d const &direct)
get coordinate from rectangle
Definition: Geometry.h:210
horizontal/vertical slicing and choose rectangle with better aspect ratio every time ...
Definition: Geometry.h:45
coordinate_traits< coordinate_type >::manhattan_area_type manhattan_area_type
manhattan area type
RectSet rectangle_set_type
internal rectangle set type
bool polygon2rectangle(InputIterator input_begin, InputIterator input_end, PointSet const &, RectSet &r, slicing_orientation_2d slicing_orient=HORIZONTAL_SLICING)
standby function for polygon-to-rectangle conversion
orientation_2d get_perpendicular() const
get perpendicular orientation
Definition: Geometry.h:124
container_traits< point_set_type >::value_type point_type
internal point type
point_traits< point_type >::coordinate_type coordinate_type
point set type for polygon
orientation_2d m_orient
orientation, HORIZONTAL or VERTICAL
namespace for Limbo
Definition: GraphUtility.h:22
std::iterator_traits< Iterator >::value_type max(Iterator first, Iterator last)
get max of an array
Definition: Math.h:61
point_compare_type(orientation_2d const &ori)
void print(string const &filename) const
print polygon to file in gnuplot format
type traits for coordinates
Definition: Geometry.h:146
bool operator()()
top api for limbo::geometry::Polygon2Rectangle
static void insert(container_type &container, value_type const &v)
insert value to container
Definition: Geometry.h:264
void F(point_type const &point, orientation_2d const &orient)
F function in the original paper remove point if found, otherwise insert.
Check string is integer, floating point, number... Convert string to upper/lower cases.
horizontal/vertical slicing and choose rectangle with larger area every time
Definition: Geometry.h:43
rectangle_set_type & m_vRect
save all rectangles from conversion
type traits for point
Definition: Geometry.h:168
static void erase(container_type &container, value_type const &v)
erase value from iterator
Definition: Geometry.h:268
Polygon2Rectangle(rectangle_set_type &vRect, InputIterator input_begin, InputIterator input_end, slicing_orientation_2d slicing_orient)
constructor
bool operator()(point_type const &p1, point_type const &p2) const
is equal helper
std::iterator_traits< Iterator >::value_type min(Iterator first, Iterator last)
get min of an array
Definition: Math.h:77
container_traits< rectangle_set_type >::value_type rectangle_type
internal rectangle type
#define assert_msg(condition, message)
assertion with message
Definition: AssertMsg.h:34
a class denoting orientation of lines
Definition: Geometry.h:92
void initialize(InputIterator input_begin, InputIterator input_end)
initialize polygon points
a template specialization for std::vector. It is more efficient than generic version ...
bool operator()(PointType const &p1, PointType const &p2) const
compare two points at specific orientation