synfig-core  1.0.3
rect.h
Go to the documentation of this file.
1 /* === S Y N F I G ========================================================= */
22 /* ========================================================================= */
23 
24 /* === S T A R T =========================================================== */
25 
26 #ifndef __SYNFIG_RECT_H
27 #define __SYNFIG_RECT_H
28 
29 /* === H E A D E R S ======================================================= */
30 
31 #include <ETL/rect>
32 #include "real.h"
33 #include "vector.h"
34 #include <limits>
35 #include <cmath>
36 
37 /* === M A C R O S ========================================================= */
38 
39 /* === T Y P E D E F S ===================================================== */
40 
41 /* === C L A S S E S & S T R U C T S ======================================= */
42 
43 namespace synfig {
44 
45 class Rect : public etl::rect<Real>
46 {
47 public:
48 
49  using etl::rect<Real>::set_point;
50  using etl::rect<Real>::expand;
51  using etl::rect<Real>::set;
52 
53  static Rect full_plane();
54 
55  static Rect horizontal_strip(const value_type &y1, const value_type &y2);
56  static Rect vertical_strip(const value_type &x1, const value_type &x2);
57 
58  static Rect zero()
59  {
60  return Rect(
61  0,
62  0,
63  0,
64  0
65  );
66  }
67 
68  static Rect infinite()
69  {
70  return Rect(
71  -INFINITY,
72  -INFINITY,
73  INFINITY,
74  INFINITY
75  );
76  }
77 
78  Rect() { }
79 
80  Rect(const Point& x) { set_point(x); }
81 
82  Rect(const Point& min, const Point& max) { set_point(min); expand(max); }
83 
84  Rect(const value_type &x1,const value_type &y1) { set_point(x1,y1); }
85 
86  Rect(const value_type &x1,const value_type &y1,
87  const value_type &x2,const value_type &y2)
88  {
89  set_point(x1,y1);
90  expand(x2,y2);
91  }
92 
93  void set_point(const Point& max) { set_point(max[0],max[1]); }
94 
95  Rect& expand(const Point& max) { expand(max[0],max[1]); return *this; }
96 
97  Rect& expand(const Real& r) { minx-=r; miny-=r; maxx+=r; maxy+=r; return *this; }
98 
99  Rect& expand_x(const Real& r) { minx-=r; maxx+=r; return *this; }
100 
101  Rect& expand_y(const Real& r) { miny-=r; maxy+=r; return *this; }
102 
103  Rect& set(const Point& min,const Point& max) { set(min[0],min[1],max[0],max[1]); return *this; }
104 
105  Point get_min()const { return Point(minx,miny); }
106  Point get_max()const { return Point(maxx,maxy); }
107 
108  bool is_inside(const Point& x) { return x[0]>minx && x[0]<maxx && x[1]>miny && x[1]<maxy; }
109 
110  Real area()const
111  {
112  return (maxx-minx)*(maxy-miny);
113  }
114 
115  // Operators
116 
117  Rect& operator+=(const Vector& rhs)
118  {
119  minx+=rhs[0]; miny+=rhs[1];
120  maxx+=rhs[0]; maxy+=rhs[1];
121  return *this;
122  }
123 
124  Rect& operator-=(const Vector& rhs)
125  {
126  minx-=rhs[0]; miny-=rhs[1];
127  maxx-=rhs[0]; maxy-=rhs[1];
128  return *this;
129  }
130 
131  Rect& operator*=(const Real& rhs)
132  {
133  minx*=rhs; miny*=rhs;
134  maxx*=rhs; maxy*=rhs;
135  return *this;
136  }
137 
139  {
140  rhs=1.0/rhs; // Avoid doing several divisions
141  minx*=rhs; miny*=rhs;
142  maxx*=rhs; maxy*=rhs;
143  return *this;
144  }
145 
146  Rect& operator&=(const Rect& rhs)
147  {
148  if(rhs.area()>0.00000001 && area()>0.00000001)
149  etl::set_intersect(*this,*this,rhs);
150  else
151  *this=zero();
152  return *this;
153  }
154 
155  Rect& operator|=(const Rect& rhs)
156  {
157  if(rhs.area()>0.00000001 && area()>0.00000001)
158  etl::set_union(*this,*this,rhs);
159  else
160  {
161  if(area()<rhs.area())
162  *this=rhs;
163  }
164  return *this;
165  }
166 
167  Rect operator+(const Vector& rhs)const { return Rect(*this)+=rhs; }
168 
169  Rect operator-(const Vector& rhs)const { return Rect(*this)-=rhs; }
170 
171  Rect operator*(const Real& rhs)const { return Rect(*this)*=rhs; }
172 
173  Rect operator/(const Real& rhs)const { return Rect(*this)/=rhs; }
174 
175  Rect operator&(const Rect& rhs)const { return Rect(*this)&=rhs; }
176 
177  Rect operator|(const Rect& rhs)const { return Rect(*this)|=rhs; }
178 
179  bool operator&&(const Rect& rhs)const { return etl::intersect(*this, rhs); }
180 
181  bool operator==(const Rect &rhs)const { return get_min() == rhs.get_min() && get_max() == rhs.get_max(); }
182 
183  bool operator!=(const Rect &rhs)const { return get_min() != rhs.get_min() || get_max() != rhs.get_max(); }
184 
185  bool is_valid()const { return valid(); }
186 
187  Rect multiply_coords(const Vector &rhs) const
188  { return Rect(minx*rhs[0], miny*rhs[1], maxx*rhs[0], maxy*rhs[1]); }
189  Rect divide_coords(const Vector &rhs) const
190  { return Rect(minx/rhs[0], miny/rhs[1], maxx/rhs[0], maxy/rhs[1]); }
191 }; // END of class Rect
192 
193 }; // END of namespace synfig
194 
195 /* === E N D =============================================================== */
196 
197 #endif