00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef IXLIB_GEOMETRY
00011 #define IXLIB_GEOMETRY
00012
00013
00014
00015
00016 #include <vector>
00017 #include <ixlib_base.hh>
00018 #include <ixlib_exgen.hh>
00019 #include <ixlib_numeric.hh>
00020
00021
00022
00023
00024
00025 namespace ixion {
00026 template <class T, int DIM = 2>
00027 class coord_vector {
00028 protected:
00029 T Data[DIM];
00030
00031 public:
00032 coord_vector()
00033 { }
00034
00035
00036
00037
00038
00039
00040
00041 template <class TP>
00042 coord_vector(coord_vector<TP,DIM> const &src) {
00043 for (int i=0; i<DIM; i++) Data[i] = src[i];
00044 }
00045
00046 coord_vector(T const x,T const y = 0,T const z = 0) {
00047 Data[0] = x;
00048 if (DIM>=2) Data[1] = y;
00049 if (DIM>=3) Data[2] = z;
00050 }
00051
00052 T &operator[](int const index)
00053 { return Data[index]; }
00054
00055 T const &operator[](int const index) const
00056 { return Data[index]; }
00057
00058 int getDimension() const
00059 { return DIM;}
00060
00061 template <class TP>
00062 bool operator==(coord_vector<TP, DIM> const &vec) const {
00063 for (int i=0; i<DIM; i++) {
00064 if (Data[i] != vec[i]) return false;
00065 }
00066 return true;
00067 }
00068
00069 template <class TP>
00070 coord_vector &operator=(TP data[]) {
00071 for (int i=0; i<DIM; i++) Data[i] = data[i];
00072 return *this;
00073 }
00074
00075 template <class TP>
00076 coord_vector &operator=(coord_vector<TP, DIM> const &vec) {
00077 for (int i=0; i<DIM; i++) Data[i] = vec[i];
00078 return *this;
00079 }
00080
00081 coord_vector operator-() const {
00082 coord_vector result;
00083 for (int i=0; i<DIM; i++) result[i] = -Data[i];
00084 return result;
00085 }
00086
00087 template <class TP>
00088 coord_vector &operator+=(coord_vector<TP> const &vec) {
00089 for (int i=0; i<DIM; i++) Data[i] += vec[i];
00090 return *this;
00091 }
00092 template <class TP>
00093 coord_vector operator+(coord_vector<TP, DIM> const &vec) const {
00094 coord_vector result;
00095 for (int i=0; i<DIM; i++) result[i] = Data[i] + vec[i];
00096 return result;
00097 }
00098
00099
00100 template <class TP>
00101 coord_vector &operator-=(coord_vector<TP, DIM> const &vec) {
00102 for (int i=0; i<DIM; i++) Data[i] -= vec[i];
00103 return *this;
00104 }
00105 template <class TP>
00106 coord_vector operator-(coord_vector<TP, DIM> const &vec) const {
00107 coord_vector result;
00108 for (int i=0; i<DIM; i++) result[i] = Data[i] - vec[i];
00109 return result;
00110 }
00111
00112 coord_vector &operator*=(T scalar) {
00113 for (int i=0; i<DIM; i++) Data[i] *= scalar;
00114 return *this;
00115 }
00116 coord_vector operator*(T scalar) const {
00117 coord_vector result;
00118 for (int i=0; i<DIM; i++) result[i] = Data[i] * scalar;
00119 return result;
00120 }
00121
00122 coord_vector &operator/=(T scalar) {
00123 for (int i=0; i<DIM; i++) Data[i] /= scalar;
00124 return *this;
00125 }
00126 coord_vector operator/(T scalar) const {
00127 coord_vector result;
00128 for (int i=0; i<DIM; i++) result[i] = Data[i] / scalar;
00129 return result;
00130 }
00131
00132 template <class TP>
00133 T operator*(coord_vector<TP, DIM> const &vec) const {
00134 T result = Data[0] * vec.Data[0];
00135 for (int i=1; i<DIM; i++) result += Data[i] * vec[i];
00136 return result;
00137 }
00138
00139 void set(T const x,T const y = 0,T const z = 0) {
00140 Data[0] = x;
00141 if (DIM>=2) Data[1] = y;
00142 if (DIM>=3) Data[2] = z;
00143 }
00144
00145 void move(T const x,T const y = 0,T const z = 0) {
00146 Data[0] += x;
00147 if (DIM>=2) Data[1] += y;
00148 if (DIM>=3) Data[2] += z;
00149 }
00150 };
00151
00152
00153
00154
00155 template <class T, int DIM>
00156 inline coord_vector<T,DIM> operator*(T scalar,coord_vector<T,DIM> const &vec) {
00157 return vec*scalar;
00158 }
00159
00160
00161
00162
00163 template<class T,int Dim>
00164 inline double getAngle(coord_vector<T,Dim> const &vec1,coord_vector<T,Dim> const &vec2) {
00165 double ip = vec1*vec2/(sqrt(vec1*vec1)*sqrt(vec2*vec2));
00166 return acos(ip);
00167 }
00168
00169
00170
00171
00172 template<class T>
00173 inline double getAngle(coord_vector<T,2> const &vec) {
00174 return atan2(vec[1],vec[0]);
00175 }
00176
00177
00178
00179
00180
00181 template <class T>
00182 struct rectangle {
00183 coord_vector<T> A,B;
00184
00185 rectangle()
00186 { }
00187 rectangle(T ax, T ay, T bx, T by)
00188 : A(ax,ay),B(bx,by)
00189 { }
00190 rectangle(coord_vector<T> const &a,coord_vector<T> const &b)
00191 : A(a),B(b)
00192 { }
00193 template <class TP>
00194 rectangle(rectangle<TP> const &src)
00195 : A(src.A),B(src.B) {
00196 }
00197
00198 template <class TP>
00199 rectangle &operator=(rectangle<TP> const &src) {
00200 A = src.A;
00201 B = src.B;
00202 return *this;
00203 }
00204
00205 T getSizeX() const
00206 { return B[0]-A[0]; }
00207 T getSizeY() const
00208 { return B[1]-A[1]; }
00209 bool doesContain(T x, T y) const
00210 { return (A[0] <= x) && (x < B[0]) && (A[1] <= y) && (y < B[1]); }
00211 bool doesContain(coord_vector<T> const &point) const
00212 { return (A[0] <= point[0]) && (point[0] < B[0]) &&
00213 (A[1] <= point[1]) && (point[1] < B[1]); }
00214 bool doesIntersect(rectangle<T> const &rect) const
00215 { return NUM_OVERLAP(A[0],B[0],rect.A[0],rect.B[0]) &&
00216 NUM_OVERLAP(A[1],B[1],rect.A[1],rect.B[1]); }
00217 bool isEmpty() const
00218 { return (B[0] <= A[0]) || (B[1] <= A[1]); }
00219
00220 void clear()
00221 { B = A; }
00222
00223 void set(T ax, T ay, T bx, T by)
00224 { A.set(ax,ay); B.set(bx,by); }
00225 template <class TP>
00226 void set(coord_vector<TP> const &a,coord_vector<TP> const &b)
00227 { A = a; B = b; }
00228
00229 void setSize(T sizex,T sizey)
00230 { B = A + coord_vector<T>(sizex,sizey); }
00231 template <class TP>
00232 void setSize(coord_vector<TP> const &p) {
00233 B = A+p;
00234 }
00235
00236 void resize(T dx,T dy)
00237 { B.move(dx,dy); }
00238 template <class TP>
00239 void resize(coord_vector<TP> const &p) {
00240 B += p;
00241 }
00242
00243 void move(T dx,T dy) {
00244 coord_vector<T> p(dx,dy);
00245 A += p; B += p;
00246 }
00247 template <class TP>
00248 void move(coord_vector<TP> const &p) {
00249 A += p; B += p;
00250 }
00251
00252 void unite(rectangle const &rect);
00253 void intersect(rectangle const &rect);
00254
00255 template <class TP>
00256 rectangle &operator+=(coord_vector<TP> const &p) {
00257 move(p);
00258 return *this;
00259 }
00260 template <class TP>
00261 rectangle operator+(coord_vector<TP> const &p) {
00262 rectangle copy(*this);
00263 copy.move(p);
00264 return copy;
00265 }
00266 template <class TP>
00267 rectangle &operator-=(coord_vector<TP> const &p) {
00268 move(p*(-1));
00269 return *this;
00270 }
00271 template <class TP>
00272 rectangle operator-(coord_vector<TP> const &p) {
00273 rectangle copy(*this);
00274 copy.move(p*(-1));
00275 return copy;
00276 }
00277 };
00278
00279
00280
00281
00282
00283 template <class T>
00284 class region {
00285 protected:
00286 vector< rectangle<T> > Rects;
00287
00288 public:
00289 typedef typename vector< rectangle<T> >::iterator iterator;
00290 typedef typename vector< rectangle<T> >::const_iterator const_iterator;
00291
00292 iterator begin()
00293 { return Rects.begin(); }
00294 const_iterator begin() const
00295 { return Rects.begin(); }
00296 iterator end()
00297 { return Rects.end(); }
00298 const_iterator end() const
00299 { return Rects.end(); }
00300
00301 void add(rectangle<T> const &rect);
00302 void intersect(rectangle<T> const &rect);
00303 void subtract(rectangle<T> const &rect);
00304 void operator+=(rectangle<T> const &rect)
00305 { add(rect); }
00306 void operator*=(rectangle<T> const &rect)
00307 { intersect(rect); }
00308 void operator-=(rectangle<T> const &rect)
00309 { subtract(rect); }
00310
00311 bool doesContain(T x, T y) const
00312 { return doesContain(coord_vector<T>(x,y)); }
00313 bool doesContain(coord_vector<T> const &point) const;
00314 bool doesIntersect(rectangle<T> const &rect) const;
00315 bool isEmpty() const
00316 { return Rects.empty(); }
00317
00318 void clear()
00319 { Rects.clear(); }
00320
00321 protected:
00322 void deleteEmptyRectangles();
00323 };
00324 }
00325
00326
00327
00328
00329 #endif