Limbo 3.5.4
Loading...
Searching...
No Matches
Polygon2Rectangle.h
Go to the documentation of this file.
1
12
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
30namespace limbo
31{
33namespace geometry
34{
35
36using std::cout;
37using std::endl;
38using std::ifstream;
39using std::ofstream;
40using std::string;
41using std::vector;
42using std::map;
43
51{
53
63
71 template <typename PointType>
72 inline bool operator()(PointType const& p1, PointType const& p2) const
73 {
74 limboAssert(m_orient.valid());
77 && point_traits<PointType>::get(p1, m_orient.get_perpendicular()) < point_traits<PointType>::get(p2, m_orient.get_perpendicular())
78 );
79 }
80};
81
88template <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 }
125
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 }
142
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 limboAssertMsg(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 limboAssert(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 limboAssert(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 limboAssert(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
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 limboAssert(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 }
320 {
321 // compute area
322 if (w*h < wref*href) // choose small area
323 itRect = it;
324 break;
325 }
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 limboAssertMsg(0, "should not reach here %d", 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 limboAssert(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 }
367
372 {
373 return m_vRect;
374 }
375
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 }
437
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:
496 inline coordinate_type get(rectangle_type const& r, direction_2d d) const {return rectangle_traits<rectangle_type>::get(r, d);}
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 };
529
535 {
536 switch (slicing_orient)
537 {
538 case HORIZONTAL_SLICING:
539 limboAssert(m_mPoint.insert(make_pair(
540 VERTICAL,
542 )).second);
543 break;
544 case VERTICAL_SLICING:
545 limboAssert(m_mPoint.insert(make_pair(
546 HORIZONTAL,
548 )).second);
549 break;
550 case HOR_VER_SLICING:
553 limboAssert(m_mPoint.insert(make_pair(
554 VERTICAL,
556 )).second);
557 limboAssert(m_mPoint.insert(make_pair(
558 HORIZONTAL,
560 )).second);
561 break;
562 default:
563 cout << "unknown slicing orientation" << endl;
564 limboAssert(0);
565 }
566 }
567
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 limboAssert(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 }
611
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 {
627 }
628 else // found, remove point
629 {
631 }
632 }
633#if 0
635 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;
675};
676
677} // namespace geometry
678} // namespace limbo
679
680// a specialization for vectors
682
683namespace limbo
684{
685namespace geometry
686{
687
697template <typename InputIterator, typename PointSet, typename RectSet>
698inline 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
assertion with message
#define limboAssertMsg(condition, args...)
custom assertion with message
Definition AssertMsg.h:24
#define limboAssert(condition)
custom assertion without message
Definition AssertMsg.h:36
Contains utilities for geometric types, such as type traits, area calculator. I'm trying to make thes...
a template specialization for std::vector. It is more efficient than generic version
Check string is integer, floating point, number... Convert string to upper/lower cases.
a class implement conversion from manhattan polygon to rectangle
bool operator()()
top api for limbo::geometry::Polygon2Rectangle
point_traits< point_type >::coordinate_type coordinate_type
point set type for polygon
void initialize(slicing_orientation_2d slicing_orient)
initialize with slicing orientation it must be called before initializing other data
void initialize(InputIterator input_begin, InputIterator input_end)
initialize polygon points
PointSet point_set_type
internal point set type
map< orientation_2d, point_set_type > m_mPoint
bool read(string const &filename)
read polygon from file try to be compatible to gnuplot format
void set(rectangle_type &r, direction_2d d, coordinate_type v) const
set coordinate of rectangle
coordinate_type get(point_type const &p, orientation_2d o) const
get coordinate from point
void print(string const &filename) const
print polygon to file in gnuplot format
rectangle_set_type const & get_rectangles() const
get rectangles
container_traits< rectangle_set_type >::value_type rectangle_type
internal rectangle 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
Polygon2Rectangle(rectangle_set_type &vRect, InputIterator input_begin, InputIterator input_end, slicing_orientation_2d slicing_orient)
constructor
coordinate_traits< coordinate_type >::manhattan_area_type manhattan_area_type
manhattan area type
Polygon2Rectangle(rectangle_set_type &vRect, slicing_orientation_2d slicing_orient=HORIZONTAL_SLICING)
constructor
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
RectSet rectangle_set_type
internal rectangle set type
rectangle_set_type & m_vRect
save all rectangles from conversion
slicing_orientation_2d m_slicing_orient
slicing orient
coordinate_type get(rectangle_type const &r, direction_2d d) const
get coordinate from rectangle
void F(point_type const &point, orientation_2d const &orient)
F function in the original paper remove point if found, otherwise insert.
coordinate_traits< coordinate_type >::coordinate_distance coordinate_distance
coordinate distance type
a class denoting orientation of lines
Definition Geometry.h:93
orientation_2d get_perpendicular() const
get perpendicular orientation
Definition Geometry.h:124
namespace for Limbo.Geometry
Definition Geometry.h:21
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
@ HOR_VER_SLICING
horizontal/vertical slicing and choose rectangle with larger area every time
Definition Geometry.h:43
@ HOR_VER_AR_SLICING
horizontal/vertical slicing and choose rectangle with better aspect ratio every time
Definition Geometry.h:45
@ HOR_VER_SA_SLICING
horizontal/vertical slicing and choose rectangle with smaller area every time
Definition Geometry.h:44
namespace for Limbo
bool is_number(string const &s)
check whether string represents a number, either integer or floating point number
Definition String.h:62
type traits for containers such as vector, list, multiset
Definition Geometry.h:282
static void insert(container_type &container, value_type const &v)
insert value to container
Definition Geometry.h:291
static container_type construct(PointCompareType const &comp)
a default construct function is necessary, because std::set needs a compare function,...
Definition Geometry.h:300
static void erase(container_type &container, value_type const &v)
erase value from iterator
Definition Geometry.h:295
type traits for coordinates
Definition Geometry.h:146
sort helper if orient == HORIZONTAL, sort by left lower if orient == VERTICAL, sort by lower left
bool operator()(PointType const &p1, PointType const &p2) const
compare two points at specific orientation
point_compare_type(orientation_2d const &ori)
orientation_2d m_orient
orientation, HORIZONTAL or VERTICAL
static coordinate_type get(const point_type &point, orientation_2d const &orient)
get coordinate from point
Definition Geometry.h:206
static point_type construct(coordinate_type const &x, coordinate_type const &y)
construct point from coordinates
Definition Geometry.h:218
static void set(point_type &point, orientation_2d const &orient, coordinate_type const &value)
set coordinate for point
Definition Geometry.h:212
static coordinate_type get(rectangle_type const &rectangle, direction_2d const &direct)
get coordinate from rectangle
Definition Geometry.h:237
static void set(rectangle_type &rectangle, direction_2d const &direct, coordinate_type const &v)
set coordinate for rectangle
Definition Geometry.h:243
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:248