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 bool operator!=(coord_vector<TP, DIM> const &vec) const {
00071 for (int i=0; i<DIM; i++) {
00072 if (Data[i] != vec[i]) return true;
00073 }
00074 return false;
00075 }
00076
00077 template <class TP>
00078 coord_vector &operator=(TP data[]) {
00079 for (int i=0; i<DIM; i++) Data[i] = data[i];
00080 return *this;
00081 }
00082
00083 template <class TP>
00084 coord_vector &operator=(coord_vector<TP, DIM> const &vec) {
00085 for (int i=0; i<DIM; i++) Data[i] = vec[i];
00086 return *this;
00087 }
00088
00089 coord_vector operator-() const {
00090 coord_vector result;
00091 for (int i=0; i<DIM; i++) result[i] = -Data[i];
00092 return result;
00093 }
00094
00095 template <class TP>
00096 coord_vector &operator+=(coord_vector<TP> const &vec) {
00097 for (int i=0; i<DIM; i++) Data[i] += vec[i];
00098 return *this;
00099 }
00100 template <class TP>
00101 coord_vector operator+(coord_vector<TP, DIM> const &vec) const {
00102 coord_vector result;
00103 for (int i=0; i<DIM; i++) result[i] = Data[i] + vec[i];
00104 return result;
00105 }
00106
00107
00108 template <class TP>
00109 coord_vector &operator-=(coord_vector<TP, DIM> const &vec) {
00110 for (int i=0; i<DIM; i++) Data[i] -= vec[i];
00111 return *this;
00112 }
00113 template <class TP>
00114 coord_vector operator-(coord_vector<TP, DIM> const &vec) const {
00115 coord_vector result;
00116 for (int i=0; i<DIM; i++) result[i] = Data[i] - vec[i];
00117 return result;
00118 }
00119
00120 coord_vector &operator*=(T scalar) {
00121 for (int i=0; i<DIM; i++) Data[i] *= scalar;
00122 return *this;
00123 }
00124 coord_vector operator*(T scalar) const {
00125 coord_vector result;
00126 for (int i=0; i<DIM; i++) result[i] = Data[i] * scalar;
00127 return result;
00128 }
00129
00130 coord_vector &operator/=(T scalar) {
00131 for (int i=0; i<DIM; i++) Data[i] /= scalar;
00132 return *this;
00133 }
00134 coord_vector operator/(T scalar) const {
00135 coord_vector result;
00136 for (int i=0; i<DIM; i++) result[i] = Data[i] / scalar;
00137 return result;
00138 }
00139
00140 template <class TP>
00141 T operator*(coord_vector<TP, DIM> const &vec) const {
00142 T result = Data[0] * vec.Data[0];
00143 for (int i=1; i<DIM; i++) result += Data[i] * vec[i];
00144 return result;
00145 }
00146
00147 void set(T const x,T const y = 0,T const z = 0) {
00148 Data[0] = x;
00149 if (DIM>=2) Data[1] = y;
00150 if (DIM>=3) Data[2] = z;
00151 }
00152
00153 void move(T const x,T const y = 0,T const z = 0) {
00154 Data[0] += x;
00155 if (DIM>=2) Data[1] += y;
00156 if (DIM>=3) Data[2] += z;
00157 }
00158 };
00159
00160
00161
00162
00163 template <class T, int DIM>
00164 inline coord_vector<T,DIM> operator*(T scalar,coord_vector<T,DIM> const &vec) {
00165 return vec*scalar;
00166 }
00167
00168
00169
00170
00171 template<class T,int Dim>
00172 inline double getAngle(coord_vector<T,Dim> const &vec1,coord_vector<T,Dim> const &vec2) {
00173 double ip = vec1*vec2/(sqrt(vec1*vec1)*sqrt(vec2*vec2));
00174 return acos(ip);
00175 }
00176
00177
00178
00179
00180 template<class T>
00181 inline double getAngle(coord_vector<T,2> const &vec) {
00182 return atan2(double(vec[1]),double(vec[0]));
00183 }
00184
00185
00186
00187
00188
00189 template <class T>
00190 struct rectangle {
00191 coord_vector<T> A,B;
00192
00193 rectangle()
00194 { }
00195 rectangle(T ax, T ay, T bx, T by)
00196 : A(ax,ay),B(bx,by)
00197 { }
00198 rectangle(coord_vector<T> const &a,coord_vector<T> const &b)
00199 : A(a),B(b)
00200 { }
00201 template <class TP>
00202 rectangle(rectangle<TP> const &src)
00203 : A(src.A),B(src.B) {
00204 }
00205
00206 template <class TP>
00207 rectangle &operator=(rectangle<TP> const &src) {
00208 A = src.A;
00209 B = src.B;
00210 return *this;
00211 }
00212
00213 T width() const {
00214 return B[0]-A[0];
00215 }
00216 T height() const {
00217 return B[1]-A[1];
00218 }
00219 T area() const {
00220 return width()*height();
00221 }
00222 bool contains(T x, T y) const {
00223 return (A[0] <= x) && (x < B[0]) && (A[1] <= y) && (y < B[1]);
00224 }
00225 bool contains(coord_vector<T> const &point) const {
00226 return (A[0] <= point[0]) && (point[0] < B[0]) &&
00227 (A[1] <= point[1]) && (point[1] < B[1]);
00228 }
00229 bool intersects(rectangle<T> const &rect) const {
00230 return NUM_OVERLAP(A[0],B[0],rect.A[0],rect.B[0]) &&
00231 NUM_OVERLAP(A[1],B[1],rect.A[1],rect.B[1]);
00232 }
00233 bool empty() const {
00234 return (B[0] <= A[0]) || (B[1] <= A[1]);
00235 }
00236
00237 void clear() {
00238 B = A;
00239 }
00240
00241 void set(T ax, T ay, T bx, T by) {
00242 A.set(ax,ay);
00243 B.set(bx,by);
00244 }
00245 template <class TP>
00246 void set(coord_vector<TP> const &a,coord_vector<TP> const &b) {
00247 A = a; B = b;
00248 }
00249
00250 void setSize(T sizex,T sizey) {
00251 B = A + coord_vector<T>(sizex,sizey);
00252 }
00253 template <class TP>
00254 void setSize(coord_vector<TP> const &p) {
00255 B = A+p;
00256 }
00257
00258 void resize(T dx,T dy) {
00259 B.move(dx,dy);
00260 }
00261 template <class TP>
00262 void resize(coord_vector<TP> const &p) {
00263 B += p;
00264 }
00265
00266 void move(T dx,T dy) {
00267 coord_vector<T> p(dx,dy);
00268 A += p; B += p;
00269 }
00270 template <class TP>
00271 void move(coord_vector<TP> const &p) {
00272 A += p; B += p;
00273 }
00274
00275 void unite(rectangle const &rect);
00276 void intersect(rectangle const &rect);
00277
00278 template <class TP>
00279 rectangle &operator+=(coord_vector<TP> const &p) {
00280 move(p);
00281 return *this;
00282 }
00283 template <class TP>
00284 rectangle operator+(coord_vector<TP> const &p) {
00285 rectangle copy(*this);
00286 copy.move(p);
00287 return copy;
00288 }
00289 template <class TP>
00290 rectangle &operator-=(coord_vector<TP> const &p) {
00291 move(p*(-1));
00292 return *this;
00293 }
00294 template <class TP>
00295 rectangle operator-(coord_vector<TP> const &p) {
00296 rectangle copy(*this);
00297 copy.move(p*(-1));
00298 return copy;
00299 }
00300
00302 T getSizeX() const {
00303 return width();
00304 }
00306 T getSizeY() const {
00307 return height();
00308 }
00310 T getWidth() const {
00311 return width();
00312 }
00314 T getHeight() const {
00315 return height();
00316 }
00318 T getArea() const {
00319 return area();
00320 }
00322 bool doesContain(T x, T y) const {
00323 return contains(x,y);
00324 }
00326 bool doesContain(coord_vector<T> const &point) const {
00327 return contains(point);
00328 }
00330 bool doesIntersect(rectangle<T> const &rect) const {
00331 return intersects(rect);
00332 }
00334 bool isEmpty() const {
00335 return empty();
00336 }
00337 };
00338
00339
00340
00341
00342
00343 template <class T>
00344 class region {
00345 protected:
00346 std::vector< rectangle<T> > Rects;
00347
00348 public:
00349 typedef typename std::vector< rectangle<T> >::iterator iterator;
00350 typedef typename std::vector< rectangle<T> >::const_iterator const_iterator;
00351
00352 TSize size() const {
00353 return Rects.size();
00354 }
00355 iterator begin() {
00356 return Rects.begin();
00357 }
00358 const_iterator begin() const {
00359 return Rects.begin();
00360 }
00361 iterator end() {
00362 return Rects.end();
00363 }
00364 const_iterator end() const {
00365 return Rects.end();
00366 }
00367
00368 void add(rectangle<T> const &rect);
00369 void intersect(rectangle<T> const &rect);
00370 void subtract(rectangle<T> const &rect);
00371 void operator+=(rectangle<T> const &rect) {
00372 add(rect);
00373 }
00374 void operator*=(rectangle<T> const &rect) {
00375 intersect(rect);
00376 }
00377 void operator-=(rectangle<T> const &rect) {
00378 subtract(rect);
00379 }
00380
00381 bool contains(T x, T y) const {
00382 return contains(coord_vector<T>(x,y));
00383 }
00384 bool contains(coord_vector<T> const &point) const;
00385 bool intersects(rectangle<T> const &rect) const;
00386 bool empty() const {
00387 return Rects.empty();
00388 }
00389
00390 void clear() {
00391 Rects.clear();
00392 }
00393
00395 bool doesContain(T x, T y) const {
00396 return contains(coord_vector<T>(x,y));
00397 }
00399 bool doesContain(coord_vector<T> const &point) const {
00400 return contains(point);
00401 }
00403 bool doesIntersect(rectangle<T> const &rect) const {
00404 return intersects(rect);
00405 }
00407 bool isEmpty() const {
00408 return empty();
00409 }
00410
00411 protected:
00412 void deleteEmptyRectangles();
00413 };
00414 }
00415
00416
00417
00418
00419 #endif