00001
00022
00023
00024
00025
00026 #ifndef __SYNFIG_RECT_H
00027 #define __SYNFIG_RECT_H
00028
00029
00030
00031 #include <ETL/rect>
00032 #include "real.h"
00033 #include "vector.h"
00034 #include <limits>
00035 #include <cmath>
00036
00037
00038
00039
00040
00041
00042
00043 namespace synfig {
00044
00045 class Rect : public etl::rect<Real>
00046 {
00047 public:
00048
00049 using etl::rect<Real>::set_point;
00050 using etl::rect<Real>::expand;
00051 using etl::rect<Real>::set;
00052
00053 static Rect full_plane();
00054
00055 static Rect horizontal_strip(const value_type &y1, const value_type &y2);
00056 static Rect vertical_strip(const value_type &x1, const value_type &x2);
00057
00058 static Rect zero()
00059 {
00060 return Rect(
00061 0,
00062 0,
00063 0,
00064 0
00065 );
00066 }
00067
00068 Rect() { }
00069
00070 Rect(const Point& x) { set_point(x); }
00071
00072 Rect(const Point& min, const Point& max) { set_point(min); expand(max); }
00073
00074 Rect(const value_type &x1,const value_type &y1) { set_point(x1,y1); }
00075
00076 Rect(const value_type &x1,const value_type &y1,
00077 const value_type &x2,const value_type &y2)
00078 {
00079 set_point(x1,y1);
00080 expand(x2,y2);
00081 }
00082
00083 void set_point(const Point& max) { set_point(max[0],max[1]); }
00084
00085 Rect& expand(const Point& max) { expand(max[0],max[1]); return *this; }
00086
00087 Rect& expand(const Real& r) { minx-=r; miny-=r; maxx+=r; maxy+=r; return *this; }
00088
00089 Rect& expand_x(const Real& r) { minx-=r; maxx+=r; return *this; }
00090
00091 Rect& expand_y(const Real& r) { miny-=r; maxy+=r; return *this; }
00092
00093 Rect& set(const Point& min,const Point& max) { set(min[0],min[1],max[0],max[1]); return *this; }
00094
00095 Point get_min()const { return Point(minx,miny); }
00096 Point get_max()const { return Point(maxx,maxy); }
00097
00098 bool is_inside(const Point& x) { return x[0]>minx && x[0]<maxx && x[1]>miny && x[1]<maxy; }
00099
00100 Real area()const
00101 {
00102 return (maxx-minx)*(maxy-miny);
00103 }
00104
00105
00106
00107 Rect& operator+=(const Vector& rhs)
00108 {
00109 minx+=rhs[0]; miny+=rhs[1];
00110 maxx+=rhs[0]; maxy+=rhs[1];
00111 return *this;
00112 }
00113
00114 Rect& operator-=(const Vector& rhs)
00115 {
00116 minx-=rhs[0]; miny-=rhs[1];
00117 maxx-=rhs[0]; maxy-=rhs[1];
00118 return *this;
00119 }
00120
00121 Rect& operator*=(const Real& rhs)
00122 {
00123 minx*=rhs; miny*=rhs;
00124 maxx*=rhs; maxy*=rhs;
00125 return *this;
00126 }
00127
00128 Rect& operator/=(Real rhs)
00129 {
00130 rhs=1.0/rhs;
00131 minx*=rhs; miny*=rhs;
00132 maxx*=rhs; maxy*=rhs;
00133 return *this;
00134 }
00135
00136 Rect& operator&=(const Rect& rhs)
00137 {
00138 if(rhs.area()>0.00000001 && area()>0.00000001)
00139 etl::set_intersect(*this,*this,rhs);
00140 else
00141 *this=zero();
00142 return *this;
00143 }
00144
00145 Rect& operator|=(const Rect& rhs)
00146 {
00147 if(rhs.area()>0.00000001 && area()>0.00000001)
00148 etl::set_union(*this,*this,rhs);
00149 else
00150 {
00151 if(area()<rhs.area())
00152 *this=rhs;
00153 }
00154 return *this;
00155 }
00156
00157 Rect operator+(const Vector& rhs)const { return Rect(*this)+=rhs; }
00158
00159 Rect operator-(const Vector& rhs)const { return Rect(*this)-=rhs; }
00160
00161 Rect operator*(const Real& rhs)const { return Rect(*this)*=rhs; }
00162
00163 Rect operator/(const Real& rhs)const { return Rect(*this)/=rhs; }
00164
00165 Rect operator&(const Rect& rhs)const { return Rect(*this)&=rhs; }
00166
00167 Rect operator|(const Rect& rhs)const { return Rect(*this)|=rhs; }
00168
00169 bool operator&&(const Rect& rhs)const { return etl::intersect(*this, rhs); }
00170
00171 bool operator==(const Rect &rhs)const { return get_min() == rhs.get_min() && get_max() == rhs.get_max(); }
00172
00173 bool operator!=(const Rect &rhs)const { return get_min() != rhs.get_min() || get_max() != rhs.get_max(); }
00174
00175 bool is_valid()const { return valid(); }
00176 };
00177
00178 };
00179
00180
00181
00182 #endif