Face.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2010
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
00026 
00027 */
00028 
00029 #include "Face.hpp"
00030 #include <list>
00031 
00036 template<unsigned DIM>
00037 bool VertexAngleComparison(const std::pair<c_vector<double, DIM>*, double> lhs, const std::pair<c_vector<double, DIM>*, double> rhs)
00038 {
00039     return lhs.second < rhs.second;
00040 }
00041 
00043 // Implementation
00045 
00046 template<unsigned DIM>
00047 void Face<DIM>::Increment(typename std::vector< c_vector<double, DIM>* >::iterator& rIterator,
00048                           Face<DIM>& rFace) const
00049 {
00050     rIterator++;
00051     if (rIterator == rFace.mVertices.end())
00052     {
00053         rIterator = rFace.mVertices.begin();
00054     }
00055 }
00056 
00057 template<unsigned DIM>
00058 bool Face<DIM>::operator==(Face<DIM>& rOtherFace)
00059 {
00060     typename std::vector< c_vector<double, DIM>* >::iterator this_iterator = mVertices.begin();
00061     typename std::vector< c_vector<double, DIM>* >::iterator other_iterator = rOtherFace.mVertices.begin();
00062 
00063     // Find first vertex
00064     while ( this_iterator != mVertices.end() &&
00065             other_iterator != rOtherFace.mVertices.end() &&
00066             norm_2(**this_iterator - **other_iterator) >1e-10 )
00067     {
00068         this_iterator++;
00069     }
00070     if (this_iterator==mVertices.end() || other_iterator==rOtherFace.mVertices.end())
00071     {
00072         // Could not find first vertex; faces are distinct unless they are empty
00073         return ( this_iterator==mVertices.end() && other_iterator==rOtherFace.mVertices.end() );
00074     }
00075 
00076     typename std::vector< c_vector<double, DIM>* >::iterator this_start = this_iterator;
00077     Increment(this_iterator, *this);
00078     Increment(other_iterator, rOtherFace);
00079 
00080     // Check remanining vertices are equal
00081     while (this_iterator != this_start)
00082     {
00083         if (norm_2(**this_iterator - **other_iterator) > 1e-10)
00084         {
00085             return false;
00086         }
00087         else
00088         {
00089             Increment(this_iterator, *this);
00090             Increment(other_iterator, rOtherFace);
00091         }
00092     }
00093     return (other_iterator == rOtherFace.mVertices.begin());
00094 }
00095 
00096 #define COVERAGE_IGNORE // Spuriously not covered
00097 template<unsigned DIM>
00098 bool Face<DIM>::operator!=(Face& rOtherFace)
00099 {
00100    return !(*this == rOtherFace);
00101 }
00102 
00103 #undef COVERAGE_IGNORE
00104 
00105 template<unsigned DIM>
00106 Face<DIM> Face<DIM>::operator-()
00107 {
00108    Face<DIM> reversed_face;
00109    typename std::vector< c_vector<double, DIM>* >::iterator this_iterator = mVertices.end();
00110    while (this_iterator != mVertices.begin())
00111    {
00112        this_iterator--;
00113        reversed_face.mVertices.push_back(*this_iterator);
00114    }
00115    return reversed_face;
00116 }
00117 
00118 template<unsigned DIM>
00119 unsigned Face<DIM>::GetNumVertices() const
00120 {
00121     return mVertices.size();
00122 }
00123 
00124 template<unsigned DIM>
00125 void Face<DIM>::OrderVerticesAntiClockwise()
00126 {
00127     assert(mVertices.size() > 1);
00128 
00129     // Compute the location of the centre of the face
00130     c_vector<double,DIM> centre = zero_vector<double>(DIM);
00131     for (unsigned j=0; j<mVertices.size(); j++)
00132     {
00133         centre += *(mVertices[j]);
00134     }
00135     centre /= mVertices.size();
00136 
00137     // Compute and store the polar angle from the centre to each vertex
00138     std::list<std::pair<c_vector<double, DIM>*, double> > vertex_angle_list;
00139     for (unsigned j=0; j<mVertices.size(); j++)
00140     {
00141         c_vector<double, DIM> centre_to_vertex = *(mVertices[j]) - centre;
00142         double angle = atan2(centre_to_vertex(1), centre_to_vertex(0));
00143 
00144         std::pair<c_vector<double, DIM>*, double> pair(mVertices[j], angle);
00145         vertex_angle_list.push_back(pair);
00146     }
00147 
00148     // Sort the list in order of increasing angle
00149     vertex_angle_list.sort(VertexAngleComparison<DIM>);
00150 
00151     // Use polar angles to reorder mVertices anticlockwise
00152     mVertices.clear();
00153     for (typename std::list<std::pair<c_vector<double, DIM>*, double> >::iterator list_iter = vertex_angle_list.begin();
00154          list_iter != vertex_angle_list.end();
00155          ++list_iter)
00156     {
00157         mVertices.push_back(list_iter->first);
00158     }
00159 }
00160 
00161 template<unsigned DIM>
00162 void Face<DIM>::AddVertex(c_vector<double, DIM>* pVertex)
00163 {
00164     mVertices.push_back(pVertex);
00165 }
00166 
00167 template<unsigned DIM>
00168 unsigned Face<DIM>::GetNumVertices()
00169 {
00170     return mVertices.size();
00171 }
00172 
00173 template<unsigned DIM>
00174 c_vector<double, DIM>& Face<DIM>::rGetVertex(unsigned index)
00175 {
00176     return *(mVertices[index]);
00177 }
00178 
00179 template<unsigned DIM>
00180 void Face<DIM>::SetVertex(unsigned index, c_vector<double, DIM>* pNewLocation)
00181 {
00182     mVertices[index] = pNewLocation;
00183 }
00184 
00186 // Explicit instantiation
00188 
00189 template class Face<1>;
00190 template class Face<2>;
00191 template class Face<3>;

Generated by  doxygen 1.6.2