ETL  0.04.19
_rect.h
Go to the documentation of this file.
1 
25 /* === S T A R T =========================================================== */
26 
27 #ifndef __ETL__RECT_H
28 #define __ETL__RECT_H
29 
30 /* === H E A D E R S ======================================================= */
31 
32 #include <functional>
33 #include <algorithm>
34 
35 /* === M A C R O S ========================================================= */
36 
37 /* === T Y P E D E F S ===================================================== */
38 
39 /* === C L A S S E S & S T R U C T S ======================================= */
40 
42 
43 template < typename T >
44 class rect
45 {
46 public: //type niceties
47  typedef T value_type;
48 
49 public: //representation
50 
52 
53 public: //interface
54 
55  rect() {}
56 
57  rect(const value_type &x1,const value_type &y1)
58  {
59  set_point(x1,y1);
60  }
61 
62  rect(const value_type &x1,const value_type &y1,
63  const value_type &x2,const value_type &y2)
64  {
65  set_point(x1,y1);
66  expand(x2,y2);
67  }
68 
69  rect(const rect<T> &o)
70  :minx(o.minx),maxx(o.maxx),miny(o.miny),maxy(o.maxy)
71  {}
72 
73  template < typename U >
74  rect(const rect<U> &o)
75  :minx(o.minx),maxx(o.maxx),miny(o.miny),maxy(o.maxy)
76  {}
77 
78  void set_point(const value_type &x1,const value_type &y1)
79  {
80  minx = maxx = x1;
81  miny = maxy = y1;
82  }
83 
84  void expand(const value_type &x1,const value_type &y1)
85  {
86  minx = std::min(minx,x1);
87  maxx = std::max(maxx,x1);
88  miny = std::min(miny,y1);
89  maxy = std::max(maxy,y1);
90  }
91 
92  void set(const value_type &x1,const value_type &y1,
93  const value_type &x2,const value_type &y2)
94  {
95  minx = x1; maxx = x2;
96  miny = y1; maxy = y2;
97  }
98 
99  //HACK HACK HACK (stupid compiler doesn't like default arguments of any type)
100  bool valid() const
101  {
102  return valid(std::less<T>());
103  }
104 
105  template < typename F >
106  bool valid(const F & func) const
107  {
108  return func(minx,maxx) && func(miny,maxy);
109  }
110 };
111 
112 template < typename T, typename F >
113 inline bool intersect(const rect<T> &r1, const rect<T> &r2, const F & func)
114 {
115  /* We wan to do the edge compare test
116  |-----|
117  |------| intersecting
118 
119  |-----|
120  |-----| not intersecting
121 
122  So we want to compare the mins of the one against the maxs of the other, and
123  visa versa
124 
125  by default (exclude edge sharing) less will not be true if they are equal...
126  */
127 
128  return func(r1.minx,r2.maxx) &&
129  func(r2.minx,r1.maxx) &&
130  func(r1.miny,r2.maxy) &&
131  func(r2.miny,r1.maxy);
132 }
133 
134 template < typename T >
135 inline bool intersect(const rect<T> &r1, const rect<T> &r2)
136 {
137  return intersect(r1,r2,std::less<T>());
138 }
139 
140 template < typename T >
141 void set_intersect(rect<T> &rout, const rect<T> &r1, const rect<T> &r2)
142 {
143  //takes the intersection of the two rectangles
144  rout.minx = std::max(r1.minx,r2.minx);
145  rout.miny = std::max(r1.miny,r2.miny);
146  rout.maxx = std::min(r1.maxx,r2.maxx);
147  rout.maxy = std::min(r1.maxy,r2.maxy);
148 }
149 
150 template < typename T >
151 void set_union(rect<T> &rout, const rect<T> &r1, const rect<T> &r2)
152 {
153  //takes the union of the two rectangles (bounds both... will contain extra info, but that's ok)
154  rout.set(
155  std::min(r1.minx,r2.minx),
156  std::min(r1.miny,r2.miny),
157  std::max(r1.maxx,r2.maxx),
158  std::max(r1.maxy,r2.maxy));
159  /*rect<T> local = r1;
160  rout.expand(r2.minx,r2.miny);
161  rout.expand(r2.maxx,r2.maxy);
162  rout = local;*/
163 }
164 
166 
167 /* === E X T E R N S ======================================================= */
168 
169 /* === E N D =============================================================== */
170 
171 #endif