00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef __IAIRect__
00019 #define __IAIRect__
00020
00021
00022
00023
00024
00025 #include "AITypes.h"
00026 #include <cmath>
00027 #include <cfloat>
00028 #include "AIBasicUtilities.h"
00029
00030 namespace ai
00031 {
00032 template<typename T>
00033 struct Absolute
00034 {
00035 static T Absolute_Val(T a){
00036 return ::abs(a);
00037 }
00038 };
00039
00040 template<>
00041 struct Absolute<AIReal>
00042 {
00043 static AIReal Absolute_Val(AIReal a){
00044 return ::fabs(a);
00045 }
00046 };
00047
00048 namespace RectTraits
00049 {
00050 template<typename T>
00051 struct RectStruct_Traits
00052 {
00053
00054 };
00055 template<>
00056 struct RectStruct_Traits <AIRect>
00057 {
00058 typedef AIPoint Point_t;
00059
00060
00061 #ifdef WIN_ENV
00062 typedef ai::int32 Coordinates_t;
00063 #endif
00064 #ifdef MAC_ENV
00065 typedef short Coordinates_t;
00066 #endif
00067 typedef Absolute<Coordinates_t> ABS_t;
00068 };
00069 template<>
00070 struct RectStruct_Traits <AIRealRect>
00071 {
00072 typedef AIRealPoint Point_t;
00073 typedef AIReal Coordinates_t;
00074 typedef Absolute<Coordinates_t> ABS_t;
00075 };
00076 }
00077 }
00078
00079
00080
00081
00082 template <typename T>
00083 class IAIRectImpl : public T
00084 {
00085 private:
00086 typedef typename ai::RectTraits::RectStruct_Traits<T>::ABS_t AbsoluteFunction;
00087 typedef typename ai::RectTraits::RectStruct_Traits<T>::Point_t PointType;
00088 typedef typename ai::RectTraits::RectStruct_Traits<T>::Coordinates_t CoordinateType;
00089 public:
00090 IAIRectImpl(){}
00091 IAIRectImpl(const T& rect)
00092 {
00093 this->left = rect.left;
00094 this->top = rect.top;
00095 this->right = rect.right;
00096 this->bottom = rect.bottom;
00097 }
00098
00099 IAIRectImpl(const PointType& a)
00100 {
00101 this->left = a.h;
00102 this->right = a.h;
00103 this->top = a.v;
00104 this->bottom = a.v;
00105 }
00106
00107 IAIRectImpl(const PointType& a, const PointType& b)
00108 {
00109 this->left = ai::Min(a.h, b.h);
00110 this->right = ai::Max(a.h, b.h);
00111 this->top = ai::Min(a.v, b.v);
00112 this->bottom = ai::Max(a.v, b.v);
00113 }
00114
00115 IAIRectImpl(CoordinateType l, CoordinateType t, CoordinateType r, CoordinateType b)
00116 {
00117 this->left = l;
00118 this->top = t;
00119 this->right = r;
00120 this->bottom = b;
00121 }
00122
00123 CoordinateType Width() const
00124 { return AbsoluteFunction::Absolute_Val(this->right - this->left);}
00125 CoordinateType Height() const
00126 { return AbsoluteFunction::Absolute_Val(this->top - this->bottom);}
00127
00128 AIBoolean IsEmpty() const
00129 { return (this->top == this->bottom && this->right == this->left); }
00130 void SetEmpty()
00131 {this->left = this->top = this->right = this->bottom = 0; }
00132
00133 AIBoolean IsNormalized() const
00134 {return this->left <= this->right && this->top <= this->bottom; }
00135 void Normalize() {
00136 if (this->left > this->right)
00137 {
00138 CoordinateType saveLeft = this->left; this->left = this->right; this->right = saveLeft;
00139 }
00140 if (this->top > this->bottom)
00141 {
00142 CoordinateType saveTop = this->top; this->top = this->bottom; this->bottom = saveTop;
00143 }
00144 }
00145
00146 AIBoolean Contains(const PointType& p) const{
00147 return this->left <= p.h && this->right >= p.h && this->top <= p.v && this->bottom >= p.v; }
00148 AIBoolean Contains(const T& r) const{
00149 return this->left <= r.left && this->right >= r.left && this->top <= r.top && this->bottom >= r.top &&
00150 this->left <= r.right && this->right >= r.right && this->top <= r.bottom && this->bottom >= r.bottom; }
00151
00152 CoordinateType Area() const
00153 {return Width() * Height(); }
00154 PointType Center() const{
00155 PointType center;
00156 center.h = (this->left + this->right) / 2;
00157 center.v = (this->top + this->bottom) / 2;
00158 return center;
00159 }
00160 AIBoolean Overlaps(const T& r) const{
00161 return this->right >= r.left && this->left <= r.right &&
00162 this->bottom >= r.top && this->top <= r.bottom;}
00163
00164 IAIRectImpl& operator ++ () {
00165 this->operator += (1); return *this; }
00166 IAIRectImpl& operator -- () {
00167 this->operator -= (1); return *this; }
00168 IAIRectImpl& operator += (CoordinateType n) {
00169 this->left -= n; this->top -= n; this->right += n; this->bottom += n; return *this; }
00170 IAIRectImpl& operator -= (CoordinateType n) {
00171 this->operator += (-n); return *this; }
00172 IAIRectImpl& operator += (const PointType& p) {
00173 this->left += p.h; this->top += p.v; this->right += p.h; this->bottom += p.v; return *this; }
00174 IAIRectImpl& operator -= (PointType& p) {
00175 this->left -= p.h; this->top -= p.v; this->right -= p.h; this->bottom -= p.v; return *this; }
00176
00177 IAIRectImpl& operator = (const PointType& p) {
00178 this->left = this->right = p.h; this->top = this->bottom = p.v;
00179 return *this; }
00180 void Inset(CoordinateType h, CoordinateType v){
00181 this->left += h; this->top += v;
00182 this->right -= h; this->bottom -= v; }
00183 void Inflate(CoordinateType h, CoordinateType v) {
00184 this->left -= h; this->top -= v;
00185 this->right += h; this->bottom += v; }
00186 void Offset(CoordinateType h, CoordinateType v){
00187 this->left += h; this->top += v;
00188 this->right += h; this->bottom += v; }
00189 void Union(const PointType& a) {
00190 this->left = ai::Min(this->left, a.h);
00191 this->top = ai::Min(this->top, a.v);
00192 this->right = ai::Max(this->right, a.h);
00193 this->bottom = ai::Max(this->bottom, a.v);
00194 }
00195 void Union(const T& a){
00196 this->left = ai::Min(a.left, this->left);
00197 this->top = ai::Min(a.top, this->top);
00198 this->right = ai:: Max(a.right, this->right);
00199 this->bottom = ai::Max( a.bottom, this->bottom);}
00200 void Union(const T& a, const T& b) {
00201 this->left = ai::Min(a.left, b.left);
00202 this->top = ai::Min(a.top, b.top);
00203 this->right = ai::Max(a.right, b.right);
00204 this->bottom = ai::Max(a.bottom, b.bottom); }
00205 void Intersect(const T& a) {
00206 this->left = ai::Max(this->left, a.left);
00207 this->top = ai::Max(this->top, a.top);
00208 this->right = ai::Min(this->right, a.right);
00209 this->bottom = ai::Min(this->bottom, a.bottom);
00210
00211 if (!Overlaps(a))
00212 SetEmpty();
00213 }
00214 void Intersect(const T& a, const T& b) {
00215 this->left = ai::Max(a.left, b.left);
00216 this->top = ai::Max(a.top, b.top);
00217 this->right = ai::Min(a.right, b.right);
00218 this->bottom = ai::Min(a.bottom, b.bottom);
00219
00220 if (!Overlaps(a))
00221 SetEmpty();
00222 }
00223
00224 void Center(const T& centerRect) {
00225 Offset(centerRect.left + ((centerRect.right - centerRect.left) - Width()) / 2,
00226 centerRect.top + ((centerRect.bottom - centerRect.top) - Height()) / 2);
00227 }
00228
00229 AIBoolean operator == (const T& a) const
00230 {
00231 return a.left == this->left &&
00232 a.top == this->top &&
00233 a.right == this->right &&
00234 a.bottom == this->bottom;
00235 }
00236 AIBoolean operator != (const T& a) const
00237 {return !(*this == a);}
00238 };
00239
00240 typedef IAIRectImpl<AIRealRect> IAIRealRect;
00241 typedef IAIRectImpl<AIRect> IAIRect;
00242
00243 #endif // __IAIRect__