1 /** 2 * SFCGAL 3 * 4 * Copyright (C) 2012-2013 Oslandia <infos@oslandia.com> 5 * Copyright (C) 2012-2013 IGN (http://www.ign.fr) 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Library General Public 9 * License as published by the Free Software Foundation; either 10 * version 2 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Library General Public License for more details. 16 17 * You should have received a copy of the GNU Library General Public 18 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #ifndef _SFCGAL_COORDINATE_H_ 22 #define _SFCGAL_COORDINATE_H_ 23 24 #include <SFCGAL/config.h> 25 26 #include <boost/assert.hpp> 27 #include <boost/array.hpp> 28 #include <boost/variant.hpp> 29 #include <boost/serialization/split_member.hpp> 30 31 #include <SFCGAL/numeric.h> 32 33 #include <SFCGAL/Kernel.h> 34 35 namespace SFCGAL { 36 37 /** 38 * @brief Represents the Coordinate of a Point (wraps either an empty structure, or a Kernel::Point_2, 39 * or a Kernel::Point_3) 40 */ 41 class SFCGAL_API Coordinate { 42 public: 43 /** 44 * Empty Coordinate constructor 45 */ 46 Coordinate() ; 47 /** 48 * XY Constructor with exact coordinates 49 */ 50 Coordinate( const Kernel::FT& x, const Kernel::FT& y ) ; 51 /** 52 * XYZ Constructor with exact coordinates 53 */ 54 Coordinate( const Kernel::FT& x, const Kernel::FT& y, const Kernel::FT& z ) ; 55 /** 56 * XYZ constructor 57 * @warning x,y,z must not be not be NaN nor inf 58 */ 59 Coordinate( const double& x, const double& y, const double& z ) ; 60 61 /** 62 * XY constructor 63 * @warning x,y must not be not be NaN nor inf 64 */ 65 Coordinate( const double& x, const double& y ) ; 66 /** 67 * Constructor from CGAL::Point_2<K> 68 */ 69 Coordinate( const Kernel::Point_2& other ) ; 70 /** 71 * Constructor from CGAL::Point_3<K> 72 */ 73 Coordinate( const Kernel::Point_3& other ) ; 74 75 /** 76 * copy constructor 77 */ 78 Coordinate( const Coordinate& other ) ; 79 /** 80 * assign operator 81 */ 82 Coordinate& operator = ( const Coordinate& other ) ; 83 /** 84 * destructor 85 */ 86 ~Coordinate() ; 87 88 /** 89 * @brief Get the dimension of the coordinates 90 */ 91 int coordinateDimension() const ; 92 /** 93 * @brief Tests if the coordinates are empty 94 */ 95 bool isEmpty() const ; 96 /** 97 * @brief Tests if Z is defined 98 */ 99 bool is3D() const ; 100 101 //--- accessors 102 103 /** 104 * @brief Gets the x value 105 * @warning Exact, NaN for empty coordinates 106 */ 107 Kernel::FT x() const; 108 109 /** 110 * @brief Gets the y value 111 * @warning Exact, NaN for empty coordinates 112 */ 113 Kernel::FT y() const; 114 115 /** 116 * @brief Gets the z value 117 * @warning Exact, NaN for empty or 0 for 2D coordinates 118 */ 119 Kernel::FT z() const; 120 121 //-- helper 122 123 /** 124 * @brief round coordinates with a scale factor 125 * @return *this 126 */ 127 Coordinate& round( const long& scaleFactor = 1 ) ; 128 129 130 //-- comparator 131 132 /** 133 * @brief Compares two points (lexicographic order) 134 * 135 * @warning coordinates must have the same dimension 136 */ 137 bool operator < ( const Coordinate& other ) const ; 138 139 /** 140 * @brief Compares with an other point 141 * 142 * @warning coordinates must have the same dimension 143 */ 144 bool operator == ( const Coordinate& other ) const ; 145 /** 146 * @brief Compares with an other point 147 * 148 * @warning coordinates must have the same dimension 149 */ 150 bool operator != ( const Coordinate& other ) const ; 151 152 /** 153 * @brief Converts to Kernel::Vector_2 154 */ toVector_2()155 inline Kernel::Vector_2 toVector_2() const { 156 return Kernel::Vector_2( CGAL::ORIGIN, toPoint_2() ); 157 } 158 159 /** 160 * @brief Converts to Kernel::Vector_3 161 */ toVector_3()162 inline Kernel::Vector_3 toVector_3() const { 163 return Kernel::Vector_3( CGAL::ORIGIN, toPoint_3() ); 164 } 165 166 /** 167 * @brief Converts to Kernel::Point_2 168 */ 169 Kernel::Point_2 toPoint_2() const; 170 171 /** 172 * @brief Converts to Kernel::Point_3 173 */ 174 Kernel::Point_3 toPoint_3() const; 175 176 // class for Empty coordinate 177 class Empty {}; 178 private: 179 boost::variant< Empty, Kernel::Point_2, Kernel::Point_3 > _storage; 180 181 public: 182 /** 183 * Serialization 184 */ 185 template <class Archive> save(Archive & ar,const unsigned int)186 void save( Archive& ar, const unsigned int /*version*/ ) const { 187 int dim = coordinateDimension(); 188 ar << dim; 189 190 if ( _storage.which() > 0 ) { 191 const Kernel::FT& x_ = x(); 192 const Kernel::FT& y_ = y(); 193 ar << x_; 194 ar << y_; 195 196 if ( _storage.which() == 2 ) { 197 const Kernel::FT& z_ = z(); 198 ar << z_; 199 } 200 } 201 } 202 203 template <class Archive> load(Archive & ar,const unsigned int)204 void load( Archive& ar, const unsigned int /*version*/ ) { 205 int dim; 206 ar >> dim; 207 208 if ( dim == 0 ) { 209 _storage = Empty(); 210 } 211 else if ( dim == 2 ) { 212 Kernel::FT x_, y_; 213 ar >> x_; 214 ar >> y_; 215 _storage = Kernel::Point_2( x_, y_ ); 216 } 217 else if ( dim == 3 ) { 218 Kernel::FT x_, y_, z_; 219 ar >> x_; 220 ar >> y_; 221 ar >> z_; 222 _storage = Kernel::Point_3( x_, y_, z_ ); 223 } 224 } 225 226 template<class Archive> serialize(Archive & ar,const unsigned int version)227 void serialize( Archive& ar, const unsigned int version ) { 228 boost::serialization::split_member( ar, *this, version ); 229 } 230 }; 231 232 233 }//SFCGAL 234 235 #endif 236