Savarese Software Research
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

Point.h

Go to the documentation of this file.
00001 /*
00002  * $Id: Point.h 5871 2005-10-28 02:10:33Z dfs $
00003  *
00004  * Copyright 2003-2005 Daniel F. Savarese
00005  * Copyright 2005 Savarese Software Research
00006  *
00007  * Licensed under the Apache License, Version 2.0 (the "License");
00008  * you may not use this file except in compliance with the License.
00009  * You may obtain a copy of the License at
00010  *
00011  *     https://www.savarese.com/software/ApacheLicense-2.0
00012  *
00013  * Unless required by applicable law or agreed to in writing, software
00014  * distributed under the License is distributed on an "AS IS" BASIS,
00015  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00016  * See the License for the specific language governing permissions and
00017  * limitations under the License.
00018  */
00019 
00026 #ifndef __SAVA_SPATIAL_POINT_H
00027 #define __SAVA_SPATIAL_POINT_H
00028 
00029 #include <limits>
00030 #include <cstring>
00031 
00032 #include <libsava/packages.h>
00033 
00034 __BEGIN_PACKAGE_SAVA_SPATIAL
00035 
00041 template<typename P>
00042 struct PointTraits {
00046   typedef P point_type;
00047 
00051   typedef typename point_type::coordinate_type coordinate_type;
00052 
00058   static inline const coordinate_type max_coordinate() {
00059     return std::numeric_limits<coordinate_type>::max();
00060   }
00061 
00067   static inline const coordinate_type min_coordinate() {
00068     return std::numeric_limits<coordinate_type>::min();
00069   }    
00070 
00076   static inline const unsigned int dimensions() {
00077     return point_type::dimensions();
00078   }
00079 };
00080 
00081 
00090 template<unsigned int Dimensions = 2, class CoordType = unsigned int>
00091 class Point {
00092 public:
00096   typedef CoordType coordinate_type;
00097 
00103   static inline const unsigned int dimensions() {
00104     return Dimensions;
00105   }
00106 
00107 private:
00108   coordinate_type coordinates[Dimensions];
00109 
00110 public:
00111 
00115   Point() {
00116     // This is the wrong thing to do for non-primitive types.
00117     // Place in a specialization of the class.
00118     std::memset(coordinates, 0, sizeof(coordinates));
00119   }
00120 
00127   coordinate_type & operator[](const unsigned int index) {
00128     return coordinates[index];
00129   }
00130 
00137   const coordinate_type & operator[](const unsigned int index) const {
00138     return coordinates[index];
00139   }
00140 
00141   // Rely on default assignment operator.
00142   /*
00143   Point & operator=(const Point & point) {
00144     // This is the wrong thing to do for non-primitive types.
00145     // Place in a specialization of the class.
00146     if(this != &point)
00147       std::memcpy(coordinates, point.coordinates, sizeof(coordinates));
00148     return *this;
00149   }
00150   */
00151 };
00152 
00153 
00162 template<unsigned int Dimensions, class CoordType>
00163 inline bool operator==(const Point<Dimensions, CoordType> & point1,
00164                        const Point<Dimensions, CoordType> & point2)
00165 {
00166   unsigned int d = Dimensions;
00167   while(d-- > 0) {
00168     if(point1[d] != point2[d])
00169       return false;
00170   }
00171   return true;
00172 }
00173 
00184 template<unsigned int Dimensions, class CoordType>
00185 inline bool operator<(const Point<Dimensions, CoordType> & point1,
00186                       const Point<Dimensions, CoordType> & point2)
00187 {
00188   unsigned int d = Dimensions;
00189   while(d-- > 0) {
00190     if(point1[d] < point2[d])
00191       return true;
00192     else if(point1[d] != point2[d])
00193       break;
00194   }
00195   return false;
00196 }
00197 
00209 template<unsigned int Dimensions, class CoordType>
00210 inline bool operator>(const Point<Dimensions, CoordType> & point1,
00211                       const Point<Dimensions, CoordType> & point2)
00212 {
00213   unsigned int d = Dimensions;
00214   while(d-- > 0) {
00215     if(point1[d] > point2[d])
00216       return true;
00217     else if(point1[d] != point2[d])
00218       break;
00219   }
00220   return false;
00221 }
00222 
00223 template<class CoordType>
00224 inline bool operator==(const Point<2, CoordType> & point1,
00225                        const Point<2, CoordType> & point2)
00226 {
00227   return (point1[0] == point2[0] && point1[1] == point2[1]);
00228 }
00229 
00230 template<class CoordType>
00231 inline bool operator<(const Point<2, CoordType> & point1,
00232                       const Point<2, CoordType> & point2)
00233 {
00234   return (point1[0] < point2[0] ||
00235           (point1[0] == point2[0] && point1[1] < point2[1]));
00236 }
00237 
00238 template<class CoordType>
00239 inline bool operator>(const Point<2, CoordType> & point1,
00240                       const Point<2, CoordType> & point2)
00241 {
00242   return (point1[0] > point2[0] ||
00243           (point1[0] == point2[0] && point1[1] > point2[1]));
00244 }
00245 
00246 template<class CoordType>
00247 inline bool operator==(const Point<3, CoordType> & point1,
00248                        const Point<3, CoordType> & point2)
00249 {
00250   return (point1[0] == point2[0] && point1[1] == point2[1] &&
00251           point1[2] == point2[2]);
00252 }
00253 
00254 template<class CoordType>
00255 inline bool operator<(const Point<3, CoordType> & point1,
00256                       const Point<3, CoordType> & point2)
00257 {
00258   return (point1[0] < point2[0] ||
00259           (point1[0] == point2[0] &&
00260            (point1[1] < point2[1] ||
00261             (point1[1] == point2[1] && point1[2] < point2[2]))));
00262            
00263 }
00264 
00265 template<class CoordType>
00266 inline bool operator>(const Point<3, CoordType> & point1,
00267                       const Point<3, CoordType> & point2)
00268 {
00269   return (point1[0] > point2[0] ||
00270           (point1[0] == point2[0] &&
00271            (point1[1] > point2[1] ||
00272             (point1[1] == point2[1] && point1[2] > point2[2]))));
00273            
00274 }
00275 
00276 template<unsigned int Dimensions, class CoordType>
00277 inline bool operator!=(const Point<Dimensions, CoordType> & point1,
00278                        const Point<Dimensions, CoordType> & point2)
00279 {
00280   return !(point1 == point2);
00281 }
00282 
00283 template<unsigned int Dimensions, class CoordType>
00284 inline bool operator>=(const Point<Dimensions, CoordType> & point1,
00285                        const Point<Dimensions, CoordType> & point2)
00286 {
00287   return !(point1 < point2);
00288 }
00289 
00290 template<unsigned int Dimensions, class CoordType>
00291 inline bool operator<=(const Point<Dimensions, CoordType> & point1,
00292                        const Point<Dimensions, CoordType> & point2)
00293 {
00294   return !(point1 > point2);
00295 }
00296 
00302 template <class CoordType = unsigned int>
00303 class Point2D : public Point<2, CoordType> {
00304 
00305 public:
00306   typedef CoordType coordinate_type;
00307 
00308   Point2D() {
00309     (*this)[0] = coordinate_type();
00310     (*this)[1] = coordinate_type();
00311   }
00312 
00313   Point2D(const coordinate_type & x, const coordinate_type & y)  {
00314     (*this)[0] = x;
00315     (*this)[1] = y;
00316   }
00317 };
00318 
00324 template <class CoordType = unsigned int>
00325 class Point3D : public Point<3, CoordType> {
00326 
00327 public:
00328   typedef CoordType coordinate_type;
00329 
00330   Point3D() {
00331     (*this)[0] = coordinate_type();
00332     (*this)[1] = coordinate_type();
00333     (*this)[2] = coordinate_type();
00334   }
00335 
00336   Point3D(const coordinate_type & x, const coordinate_type & y,
00337           const coordinate_type & z)
00338   {
00339     (*this)[0] = x;
00340     (*this)[1] = y;
00341     (*this)[2] = z;
00342   }
00343 };
00344 
00345 
00346 // Will have to replace isContained with an abstraction for testing
00347 // containment in arbitrarily shaped regions.
00348 
00349 template <unsigned int Dimensions, class CoordType>
00350 inline bool isContained(const Point<Dimensions, CoordType> & point,
00351                         const Point<Dimensions, CoordType> & lower,
00352                         const Point<Dimensions, CoordType> & upper)
00353 {
00354   for(unsigned int i = 0; i < Dimensions; ++i) {
00355     if(point[i] < lower[i] || point[i] > upper[i])
00356       return false;
00357   }
00358 
00359   return true;
00360 }
00361 
00362 
00363 template <class CoordType>
00364 inline bool isContained(const Point<2, CoordType> & point,
00365                         const Point<2, CoordType> & lower,
00366                         const Point<2, CoordType> & upper)
00367 {
00368   return !(point[0] < lower[0] || point[1] < lower[1] ||
00369            point[0] > upper[0] || point[1] > upper[1]);
00370 }
00371 
00372 
00373 template <class CoordType>
00374 inline bool isContained(const Point<3, CoordType> & point,
00375                         const Point<3, CoordType> & lower,
00376                         const Point<3, CoordType> & upper)
00377 {
00378   return !(point[0] < lower[0] || point[1] < lower[1] || point[2] < lower[2] ||
00379            point[0] > upper[0] || point[1] > upper[1] || point[2] > upper[2]);
00380 
00381 }
00382 
00383 __END_PACKAGE_SAVA_SPATIAL
00384 
00385 #endif

Savarese Software Research
Copyright © 2003-2005 Savarese Software Research and Daniel F. Savarese. All rights reserved.