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 getWidth() const {
00214 return B[0]-A[0];
00215 }
00216 T getHeight() const {
00217 return B[1]-A[1];
00218 }
00219 T getArea() const {
00220 return getWidth()*getHeight();
00221 }
00222 bool doesContain(T x, T y) const {
00223 return (A[0] <= x) && (x < B[0]) && (A[1] <= y) && (y < B[1]);
00224 }
00225 bool doesContain(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 doesIntersect(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 isEmpty() const {
00234 return (B[0] <= A[0]) || (B[1] <= A[1]); }
00235
00236 void clear() {
00237 B = A;
00238 }
00239
00240 void set(T ax, T ay, T bx, T by) {
00241 A.set(ax,ay);
00242 B.set(bx,by);
00243 }
00244 template <class TP>
00245 void set(coord_vector<TP> const &a,coord_vector<TP> const &b) {
00246 A = a; B = b;
00247 }
00248
00249 void setSize(T sizex,T sizey) {
00250 B = A + coord_vector<T>(sizex,sizey);
00251 }
00252 template <class TP>
00253 void setSize(coord_vector<TP> const &p) {
00254 B = A+p;
00255 }
00256
00257 void resize(T dx,T dy) {
00258 B.move(dx,dy);
00259 }
00260 template <class TP>
00261 void resize(coord_vector<TP> const &p) {
00262 B += p;
00263 }
00264
00265 void move(T dx,T dy) {
00266 coord_vector<T> p(dx,dy);
00267 A += p; B += p;
00268 }
00269 template <class TP>
00270 void move(coord_vector<TP> const &p) {
00271 A += p; B += p;
00272 }
00273
00274 void unite(rectangle const &rect);
00275 void intersect(rectangle const &rect);
00276
00277 template <class TP>
00278 rectangle &operator+=(coord_vector<TP> const &p) {
00279 move(p);
00280 return *this;
00281 }
00282 template <class TP>
00283 rectangle operator+(coord_vector<TP> const &p) {
00284 rectangle copy(*this);
00285 copy.move(p);
00286 return copy;
00287 }
00288 template <class TP>
00289 rectangle &operator-=(coord_vector<TP> const &p) {
00290 move(p*(-1));
00291 return *this;
00292 }
00293 template <class TP>
00294 rectangle operator-(coord_vector<TP> const &p) {
00295 rectangle copy(*this);
00296 copy.move(p*(-1));
00297 return copy;
00298 }
00299
00300
00301 T getSizeX() const
00302 { return B[0]-A[0]; }
00303 T getSizeY() const
00304 { return B[1]-A[1]; }
00305 };
00306
00307
00308
00309
00310
00311 template <class T>
00312 class region {
00313 protected:
00314 std::vector< rectangle<T> > Rects;
00315
00316 public:
00317 typedef typename std::vector< rectangle<T> >::iterator iterator;
00318 typedef typename std::vector< rectangle<T> >::const_iterator const_iterator;
00319
00320 TSize size() const {
00321 return Rects.size();
00322 }
00323 iterator begin() {
00324 return Rects.begin();
00325 }
00326 const_iterator begin() const {
00327 return Rects.begin();
00328 }
00329 iterator end() {
00330 return Rects.end();
00331 }
00332 const_iterator end() const {
00333 return Rects.end();
00334 }
00335
00336 void add(rectangle<T> const &rect);
00337 void intersect(rectangle<T> const &rect);
00338 void subtract(rectangle<T> const &rect);
00339 void operator+=(rectangle<T> const &rect) {
00340 add(rect);
00341 }
00342 void operator*=(rectangle<T> const &rect) {
00343 intersect(rect);
00344 }
00345 void operator-=(rectangle<T> const &rect) {
00346 subtract(rect);
00347 }
00348
00349 bool doesContain(T x, T y) const {
00350 return doesContain(coord_vector<T>(x,y));
00351 }
00352 bool doesContain(coord_vector<T> const &point) const;
00353 bool doesIntersect(rectangle<T> const &rect) const;
00354 bool isEmpty() const {
00355 return Rects.empty();
00356 }
00357
00358 void clear() {
00359 Rects.clear();
00360 }
00361
00362 protected:
00363 void deleteEmptyRectangles();
00364 };
00365 }
00366
00367
00368
00369
00370 #endif