9#ifndef _LIMBO_GEOMETRY_POLYGON2RECTANGLEVEC_H
10#define _LIMBO_GEOMETRY_POLYGON2RECTANGLEVEC_H
24template <
typename PointSet,
32template <
typename PointType,
33 typename RectangleType>
43 typedef typename container_traits<point_set_type>::value_type
point_type;
48 typedef typename container_traits<rectangle_set_type>::value_type
rectangle_type;
65 :
m_mPoint((slicing_orient != HORIZONTAL_SLICING && slicing_orient != VERTICAL_SLICING)? 2 : 1)
80 template <
typename InputIterator>
82 :
m_mPoint((slicing_orient != HORIZONTAL_SLICING && slicing_orient != VERTICAL_SLICING)? 2 : 1)
96 template <
typename InputIterator>
97 void initialize(InputIterator input_begin, InputIterator input_end)
104 std::vector<point_type> vTmpPoint;
105 InputIterator input_last = input_begin;
106 std::size_t dist = std::distance(input_begin, input_end);
107 std::advance(input_last, dist-1);
113 vTmpPoint.reserve(dist);
115 for (InputIterator itPrev = input_begin; itPrev != input_end; ++itPrev)
117 InputIterator itCur = itPrev;
119 if (itCur == input_end)
121 InputIterator itNext = itCur;
123 if (itNext == input_end)
124 itNext = input_begin;
131 if (this->
get(*itPrev, HORIZONTAL) == this->
get(*itCur, HORIZONTAL)
132 && this->
get(*itCur, HORIZONTAL) == this->
get(*itNext, HORIZONTAL))
135 limboAssert(std::min(this->
get(*itPrev, VERTICAL), this->
get(*itNext, VERTICAL)) <= this->
get(*itCur, VERTICAL)
136 && std::max(this->
get(*itPrev, VERTICAL), this->
get(*itNext, VERTICAL)) >= this->
get(*itCur, VERTICAL));
140 else if (this->
get(*itPrev, VERTICAL) == this->
get(*itCur, VERTICAL)
141 && this->
get(*itCur, VERTICAL) == this->
get(*itNext, VERTICAL))
144 limboAssert(std::min(this->
get(*itPrev, HORIZONTAL), this->
get(*itNext, HORIZONTAL)) <= this->
get(*itCur, HORIZONTAL)
145 && std::max(this->
get(*itPrev, HORIZONTAL), this->
get(*itNext, HORIZONTAL)) >= this->
get(*itCur, HORIZONTAL));
154 this->
get(*itCur, HORIZONTAL),
155 this->
get(*itCur, VERTICAL)
168 vPointFront.reserve(vTmpPoint.size());
169 for (
typename std::vector<point_type>::iterator itCur = vTmpPoint.begin(), itCure = vTmpPoint.end(); itCur != itCure; ++itCur)
171 typename std::vector<point_type>::iterator itNext = itCur;
173 if (itNext == itCure)
174 itNext = vTmpPoint.begin();
176 vPointFront.push_back(*itCur);
180 if (itCur == itCure)
break;
185 for (std::size_t i = 1, ie =
m_mPoint.size(); i < ie; ++i)
192 vPoint.swap(vTmpPoint);
194 vPoint.assign(vPointPrev.begin(), vPointPrev.end());
206 std::vector<rectangle_type> vRect (
m_mPoint.size());
208 while (!
m_mPoint.front().second.empty())
212 for (
typename std::vector<std::pair<orientation_2d, point_set_type> >::const_iterator it =
m_mPoint.begin();
232 this->
get(Pk, HORIZONTAL),
233 this->
get(Pk, VERTICAL),
234 std::max(this->
get(Pl, HORIZONTAL), this->
get(Pm, HORIZONTAL)),
235 std::max(this->
get(Pl, VERTICAL), this->
get(Pm, VERTICAL)));
238 if (this->
get(rect, RIGHT) > std::numeric_limits<coordinate_type>::max()-1000
239 || this->
get(rect, TOP) > std::numeric_limits<coordinate_type>::max()-1000)
244 typename std::vector<rectangle_type>::iterator itRect = vRect.begin();
245 for (
typename std::vector<rectangle_type>::iterator it = ++vRect.begin(); it != vRect.end(); ++it)
276 if (minDelta > maxDelta)
277 std::swap(minDelta, maxDelta);
278 if (minDeltaRef > maxDeltaRef)
279 std::swap(minDeltaRef, maxDeltaRef);
281 if (maxDelta*minDeltaRef < minDelta*maxDeltaRef)
290 for (
typename std::vector<std::pair<orientation_2d, point_set_type> >::iterator it =
m_mPoint.begin();
323 bool read(
string const& filename)
325 ifstream in (filename.c_str());
328 cout <<
"failed to open " << filename << endl;
336 std::vector<point_type> vPoint;
341 if (tag ==
"polygon" && status == 0)
345 else if (tag ==
"from" || tag ==
"to")
351 while (!in.eof() && i < 2)
354 boost::trim_if(value_str, boost::is_any_of(
", \t\\"));
357 value[i] = boost::lexical_cast<coordinate_type>(value_str);
363 if (i != 2)
return false;
366 this->
set(vPoint.back(), HORIZONTAL, value[0]);
367 this->
set(vPoint.back(), VERTICAL, value[1]);
369 else if (status == 1)
376 this->
initialize(vPoint.begin(), vPoint.end());
384 void print(
string const& filename)
const
386 ofstream out (filename.c_str());
389 cout <<
"failed to open " << filename << endl;
395 if (vPoint.size() > 0)
397 out <<
"set obj " << i++ <<
" ";
398 out <<
"polygon \\" << endl;
399 for (
typename point_set_type::const_iterator it = vPoint.begin(), ite = vPoint.end(); it != ite; ++it)
401 if (it == vPoint.begin())
402 out <<
"from " << this->
get(*it, HORIZONTAL) <<
", " << this->
get(*it, VERTICAL) <<
" \\" << endl;
404 out <<
"to " << this->
get(*it, HORIZONTAL) <<
", " << this->
get(*it, VERTICAL) <<
" \\" << endl;
410 for (
typename rectangle_set_type::const_iterator it =
m_vRect.begin(); it !=
m_vRect.end(); ++it)
413 out <<
"set obj " << i <<
" rectangle ";
414 out <<
"from " << this->
get(*it, LEFT) <<
", " << this->
get(*it, BOTTOM) <<
" "
415 <<
"to " << this->
get(*it, RIGHT) <<
", " << this->
get(*it, TOP) <<
" ";
416 out <<
"fc rgb \"dark-grey\" fs transparent pattern 4 bo"<< endl;
418 out <<
"set label \'" << i <<
"\' at "
419 << (this->
get(*it, LEFT)+this->
get(*it, RIGHT))/2.0 <<
", " << (this->
get(*it, BOTTOM)+this->
get(*it, TOP))/2.0 <<
" "
420 <<
"front center tc rgb \"black\"" << endl;
479 switch (slicing_orient)
482 case HORIZONTAL_SLICING:
486 case VERTICAL_SLICING:
499 std::cout <<
"unknown slicing orientation" << std::endl;
515 if (vPoint.size() < 4)
520 this->
set(Pk, HORIZONTAL, this->
get(*vPoint.begin(), HORIZONTAL));
521 this->
set(Pk, VERTICAL, this->
get(*vPoint.begin(), VERTICAL));
523 this->
set(Pl, HORIZONTAL, this->
get(*(++(vPoint.begin())), HORIZONTAL));
524 this->
set(Pl, VERTICAL, this->
get(*(++(vPoint.begin())), VERTICAL));
526 this->
set(Pm, HORIZONTAL, std::numeric_limits<coordinate_type>::max());
527 this->
set(Pm, VERTICAL, std::numeric_limits<coordinate_type>::max());
528 for (
typename point_set_type::const_iterator it = vPoint.begin(), ite = vPoint.end(); it != ite; ++it)
530 if (this->
get(Pk, orient) == this->
get(*it, orient))
536 this->
set(Pm, HORIZONTAL, this->
get(*it, HORIZONTAL));
537 this->
set(Pm, VERTICAL, this->
get(*it, VERTICAL));
541 if (this->
get(Pm, HORIZONTAL) == std::numeric_limits<coordinate_type>::max()
542 || this->
get(Pm, VERTICAL) == std::numeric_limits<coordinate_type>::max())
558 typename point_set_type::iterator itr = std::lower_bound(vPoint.begin(), vPoint.end(), point,
point_compare_type(orient));
569 std::vector<std::pair<orientation_2d, point_set_type> >
m_mPoint;
#define limboAssertMsg(condition, args...)
custom assertion with message
#define limboAssert(condition)
custom assertion without message
coordinate_type get(point_type const &p, orientation_2d o) const
get coordinate from point
void F(point_type const &point, orientation_2d const &orient)
F function in the original paper remove point if found, otherwise insert.
rectangle_set_type & m_vRect
save all rectangles from conversion
std::vector< std::pair< orientation_2d, point_set_type > > m_mPoint
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
std::vector< PointType > point_set_type
internal point set type
void initialize(slicing_orientation_2d slicing_orient)
initialize with slicing orientation it must be called before initializing other data
Polygon2Rectangle(rectangle_set_type &vRect, InputIterator input_begin, InputIterator input_end, slicing_orientation_2d slicing_orient)
constructor
std::vector< unsigned char > m_vOrient2Id
orientation_2d to index of m_mPoint
point_traits< point_type >::coordinate_type coordinate_type
point set type for polygon
bool read(string const &filename)
read polygon from file try to be compatible to gnuplot format
Polygon2Rectangle(rectangle_set_type &vRect, slicing_orientation_2d slicing_orient=HORIZONTAL_SLICING)
constructor
coordinate_traits< coordinate_type >::manhattan_area_type manhattan_area_type
manhattan area type
std::vector< RectangleType > rectangle_set_type
internal rectangle set type
coordinate_type get(rectangle_type const &r, direction_2d d) const
get coordinate from rectangle
bool operator()()
top api for limbo::geometry::Polygon2Rectangle
slicing_orientation_2d m_slicing_orient
slicing orient
container_traits< point_set_type >::value_type point_type
internal point type
void set(rectangle_type &r, direction_2d d, coordinate_type v) const
set coordinate of rectangle
container_traits< rectangle_set_type >::value_type rectangle_type
internal rectangle type
coordinate_traits< coordinate_type >::coordinate_distance coordinate_distance
coordinate distance type
rectangle_set_type const & get_rectangles() const
get rectangles
void set(point_type &p, orientation_2d o, coordinate_type v) const
set coordinate of point
void print(string const &filename) const
print polygon to file in gnuplot format
void initialize(InputIterator input_begin, InputIterator input_end)
initialize polygon points
a class implement conversion from manhattan polygon to rectangle
bool operator()()
top api for limbo::geometry::Polygon2Rectangle
void initialize(InputIterator input_begin, InputIterator input_end)
initialize polygon points
coordinate_type get(point_type const &p, orientation_2d o) const
get coordinate from point
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
container_traits< point_set_type >::value_type point_type
internal point type
void set(point_type &p, orientation_2d o, coordinate_type v) const
set coordinate of point
void F(point_type const &point, orientation_2d const &orient)
F function in the original paper remove point if found, otherwise insert.
a class denoting orientation of lines
int to_int() const
convert orientation to integer
orientation_2d get_perpendicular() const
get perpendicular orientation
namespace for Limbo.Geometry
@ HOR_VER_SLICING
horizontal/vertical slicing and choose rectangle with larger area every time
@ HOR_VER_AR_SLICING
horizontal/vertical slicing and choose rectangle with better aspect ratio every time
@ HOR_VER_SA_SLICING
horizontal/vertical slicing and choose rectangle with smaller area every time
std::iterator_traits< Iterator >::value_type max(Iterator first, Iterator last)
get max of an array
bool is_number(string const &s)
check whether string represents a number, either integer or floating point number
type traits for containers such as vector, list, multiset
static void insert(container_type &container, value_type const &v)
insert value to container
static void erase(container_type &container, value_type const &v)
erase value from iterator
type traits for coordinates
sort helper if orient == HORIZONTAL, sort by left lower if orient == VERTICAL, sort by lower left
static coordinate_type get(const point_type &point, orientation_2d const &orient)
get coordinate from point
static point_type construct(coordinate_type const &x, coordinate_type const &y)
construct point from coordinates
static void set(point_type &point, orientation_2d const &orient, coordinate_type const &value)
set coordinate for point
static coordinate_type get(rectangle_type const &rectangle, direction_2d const &direct)
get coordinate from rectangle
static void set(rectangle_type &rectangle, direction_2d const &direct, coordinate_type const &v)
set coordinate for rectangle
static rectangle_type construct(coordinate_type const &xl, coordinate_type const &yl, coordinate_type const &xh, coordinate_type const &yh)
construct rectangle from coordinates