00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef FACE_HPP_
00031 #define FACE_HPP_
00032
00033 #include "UblasCustomFunctions.hpp"
00034 #include <vector>
00035 #include "Exception.hpp"
00036
00037 template <unsigned DIM>
00038 class Face
00039 {
00040 public:
00044 std::vector< c_vector<double, DIM>* > mVertices;
00045
00046 private:
00047 void Increment(typename std::vector< c_vector<double, DIM>* >::iterator& rIterator,
00048 Face<DIM>& rFace) const;
00049
00050 public:
00051
00052
00053 class VertexAndAngle
00054 {
00055 public:
00056 c_vector< double ,DIM >* mpVertex;
00057 double mAngle;
00058 bool operator<(const VertexAndAngle& other) const
00059 {
00060 return mAngle < other.mAngle;
00061 }
00062 };
00063
00064
00069 bool operator==(Face<DIM>& otherFace);
00070
00074 bool operator!=(Face<DIM>& otherFace);
00075
00079 Face<DIM> operator-();
00080
00086 double GetPerimeter() const;
00087
00093 double GetArea() const;
00094
00098 unsigned GetNumVertices() const;
00099
00103 std::vector< c_vector<double, DIM>* > GetVertices() const;
00104
00105
00109 void OrderVerticesAntiClockwise();
00110
00116 double ReturnPolarAngle(double x, double y) const;
00117
00118 };
00119
00120
00121
00122 template <unsigned DIM>
00123 void Face<DIM>::Increment(typename std::vector< c_vector<double, DIM>* >::iterator& rIterator,
00124 Face<DIM>& rFace) const
00125 {
00126 rIterator++;
00127 if (rIterator==rFace.mVertices.end() )
00128 {
00129 rIterator=rFace.mVertices.begin();
00130 }
00131 };
00132
00133 template <unsigned DIM>
00134 bool Face<DIM>::operator==(Face<DIM>& otherFace)
00135 {
00136 typename std::vector< c_vector<double, DIM>* >::iterator this_iterator=mVertices.begin();
00137 typename std::vector< c_vector<double, DIM>* >::iterator other_iterator=otherFace.mVertices.begin();
00138
00139 while ( this_iterator!=mVertices.end() &&
00140 other_iterator!=otherFace.mVertices.end() &&
00141 norm_2(**this_iterator - **other_iterator) >1e-10 )
00142 {
00143 this_iterator++;
00144 }
00145 if (this_iterator==mVertices.end() || other_iterator==otherFace.mVertices.end())
00146 {
00147
00148
00149 return this_iterator==mVertices.end() && other_iterator==otherFace.mVertices.end();
00150 }
00151
00152 typename std::vector< c_vector<double, DIM>* >::iterator this_start=this_iterator;
00153 Increment(this_iterator, *this);
00154 Increment(other_iterator, otherFace);
00155
00156
00157 while (this_iterator!=this_start)
00158 {
00159 if (norm_2(**this_iterator - **other_iterator) >1e-10)
00160 {
00161 return false;
00162 }
00163 else
00164 {
00165 Increment(this_iterator, *this);
00166 Increment(other_iterator, otherFace);
00167 }
00168 }
00169 return other_iterator==otherFace.mVertices.begin();
00170 };
00171
00172 #define COVERAGE_IGNORE //Spuriously not covered
00173 template <unsigned DIM>
00174 bool Face<DIM>::operator!=(Face& otherFace)
00175 {
00176 return !(*this==otherFace);
00177 };
00178 #undef COVERAGE_IGNORE
00179
00180 template <unsigned DIM>
00181 Face<DIM> Face<DIM>::operator-()
00182 {
00183 Face<DIM> reversed_face;
00184 typename std::vector< c_vector<double, DIM>* >::iterator this_iterator=mVertices.end();
00185 while (this_iterator !=mVertices.begin())
00186 {
00187 this_iterator--;
00188 reversed_face.mVertices.push_back(*this_iterator);
00189 }
00190 return reversed_face;
00191 };
00192
00193 template <unsigned DIM>
00194 double Face<DIM>::GetPerimeter() const
00195 {
00196 double perimeter_return = 0;
00197 for(unsigned i=0; i<mVertices.size(); i++)
00198 {
00199 perimeter_return += norm_2(*mVertices[i]-*mVertices[(i+1)%mVertices.size()]);
00200 }
00201 return perimeter_return;
00202 };
00203
00204 template <unsigned DIM>
00205 double Face<DIM>::GetArea() const
00206 {
00207 #define COVERAGE_IGNORE
00208 assert(DIM==2);
00209 #undef COVERAGE_IGNORE
00210
00211 double area_return = 0;
00212 for(unsigned i=0; i<mVertices.size(); i++)
00213 {
00214
00215
00216 area_return += ( (*mVertices[i])(0) * (*mVertices[(i+1)%mVertices.size()])(1)
00217 -(*mVertices[i])(1) * (*mVertices[(i+1)%mVertices.size()])(0) ) / 2.0;
00218 }
00219 return area_return;
00220 };
00221
00222 template <unsigned DIM>
00223 unsigned Face<DIM>::GetNumVertices() const
00224 {
00225 return mVertices.size();
00226 };
00227
00228 template <unsigned DIM>
00229 std::vector< c_vector<double, DIM>* > Face<DIM>::GetVertices() const
00230 {
00231 return mVertices;
00232 };
00233
00234 template<unsigned DIM>
00235 double Face<DIM>::ReturnPolarAngle(double x, double y) const
00236 {
00237 if (x==0)
00238 {
00239 if (y>0)
00240 {
00241 return M_PI/2.0;
00242 }
00243 else if (y<0)
00244 {
00245 return -M_PI/2.0;
00246 }
00247 else
00248 {
00249 EXCEPTION("Tried to compute polar angle of (0,0)");
00250 }
00251 }
00252
00253 double angle = atan(y/x);
00254
00255 if (y >= 0 && x < 0 )
00256 {
00257 angle += M_PI;
00258 }
00259 else if (y < 0 && x < 0 )
00260 {
00261 angle -= M_PI;
00262 }
00263 return angle;
00264 };
00265
00266
00267
00268 template <unsigned DIM>
00269 void Face<DIM>::OrderVerticesAntiClockwise()
00270 {
00271
00272 std::vector< VertexAndAngle > vertices_and_angles;
00273
00274 c_vector<double,DIM> centre = zero_vector<double>(DIM);
00275
00276 for(unsigned j=0; j<mVertices.size(); j++)
00277 {
00278
00279 centre += *(mVertices[j]);
00280 }
00281
00282 centre /= mVertices.size();
00283 for(unsigned j=0; j<mVertices.size(); j++)
00284 {
00285
00286 VertexAndAngle va;
00287 c_vector<double, DIM> centre_to_vertex;
00288
00289 centre_to_vertex = *(mVertices[j]) - centre;
00290 va.mAngle = ReturnPolarAngle(centre_to_vertex(0), centre_to_vertex(1));
00291 va.mpVertex = mVertices[j];
00292 vertices_and_angles.push_back(va);
00293 }
00294
00295 std::sort(vertices_and_angles.begin(), vertices_and_angles.end());
00296
00297
00298 mVertices.clear();
00299 for ( typename std::vector< VertexAndAngle >::iterator vertex_iterator = vertices_and_angles.begin();
00300 vertex_iterator !=vertices_and_angles.end();
00301 vertex_iterator++)
00302 {
00303 mVertices.push_back(vertex_iterator->mpVertex);
00304 }
00305 };
00306
00307
00308 #endif