Face.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2009
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 
00032 // Implementation
00034 
00035 template<unsigned DIM>
00036 void Face<DIM>::Increment(typename std::vector< c_vector<double, DIM>* >::iterator& rIterator,
00037                           Face<DIM>& rFace) const
00038 {
00039     rIterator++;
00040     if (rIterator == rFace.mVertices.end())
00041     {
00042         rIterator = rFace.mVertices.begin();
00043     }
00044 }
00045 
00046 template<unsigned DIM>
00047 bool Face<DIM>::operator==(Face<DIM>& rOtherFace)
00048 {
00049     typename std::vector< c_vector<double, DIM>* >::iterator this_iterator = mVertices.begin();
00050     typename std::vector< c_vector<double, DIM>* >::iterator other_iterator = rOtherFace.mVertices.begin();
00051 
00052     // Find first vertex
00053     while ( this_iterator != mVertices.end() &&
00054             other_iterator != rOtherFace.mVertices.end() &&
00055             norm_2(**this_iterator - **other_iterator) >1e-10 )
00056     {
00057         this_iterator++;
00058     }
00059     if (this_iterator==mVertices.end() || other_iterator==rOtherFace.mVertices.end())
00060     {
00061         // Could not find first vertex; faces are distinct unless they are empty
00062         return ( this_iterator==mVertices.end() && other_iterator==rOtherFace.mVertices.end() );
00063     }
00064 
00065     typename std::vector< c_vector<double, DIM>* >::iterator this_start = this_iterator;
00066     Increment(this_iterator, *this);
00067     Increment(other_iterator, rOtherFace);
00068 
00069     // Check remanining vertices are equal
00070     while (this_iterator != this_start)
00071     {
00072         if (norm_2(**this_iterator - **other_iterator) > 1e-10)
00073         {
00074             return false;
00075         }
00076         else
00077         {
00078             Increment(this_iterator, *this);
00079             Increment(other_iterator, rOtherFace);
00080         }
00081     }
00082     return (other_iterator == rOtherFace.mVertices.begin());
00083 }
00084 
00085 #define COVERAGE_IGNORE // Spuriously not covered
00086 template<unsigned DIM>
00087 bool Face<DIM>::operator!=(Face& rOtherFace)
00088 {
00089    return !(*this == rOtherFace);
00090 }
00091 
00092 #undef COVERAGE_IGNORE
00093 
00094 template<unsigned DIM>
00095 Face<DIM> Face<DIM>::operator-()
00096 {
00097    Face<DIM> reversed_face;
00098    typename std::vector< c_vector<double, DIM>* >::iterator this_iterator = mVertices.end();
00099    while (this_iterator != mVertices.begin())
00100    {
00101        this_iterator--;
00102        reversed_face.mVertices.push_back(*this_iterator);
00103    }
00104    return reversed_face;
00105 }
00106 
00107 template<unsigned DIM>
00108 double Face<DIM>::GetPerimeter() const
00109 {
00110     double perimeter_return = 0;
00111     for (unsigned i=0; i<mVertices.size(); i++)
00112     {
00113         perimeter_return += norm_2(*mVertices[i]-*mVertices[(i+1)%mVertices.size()]);
00114     }
00115     return perimeter_return;
00116 }
00117 
00118 template<unsigned DIM>
00119 double Face<DIM>::GetArea() const
00120 {
00121     #define COVERAGE_IGNORE
00122     assert(DIM==2);
00123     #undef COVERAGE_IGNORE
00124 
00125     double area_return = 0;
00126     for (unsigned i=0; i<mVertices.size(); i++)
00127     {
00128         //  Area = sum ( x_i * y_i+1 - y_i * x_i+1 )/2.0 over all vertices,
00129         //      assuming vertices are ordered anti-clockwise
00130         area_return += ( (*mVertices[i])(0) * (*mVertices[(i+1)%mVertices.size()])(1)
00131                         -(*mVertices[i])(1) * (*mVertices[(i+1)%mVertices.size()])(0) ) / 2.0;
00132     }
00133     return area_return;
00134 }
00135 
00136 template<unsigned DIM>
00137 unsigned Face<DIM>::GetNumVertices() const
00138 {
00139     return mVertices.size();
00140 }
00141 
00142 template<unsigned DIM>
00143 std::vector< c_vector<double, DIM>* > Face<DIM>::GetVertices() const
00144 {
00145     return mVertices;
00146 }
00147 
00148 template<unsigned DIM>
00149 void Face<DIM>::OrderVerticesAntiClockwise()
00150 {
00151     // Reorder mVertices anticlockwise
00152     std::vector<VertexAndAngle<DIM> > vertices_and_angles;
00153 
00154     c_vector<double,DIM> centre = zero_vector<double>(DIM);
00155 
00156     for (unsigned j=0; j<mVertices.size(); j++)
00157     {
00158         centre += *(mVertices[j]);
00159     }
00160 
00161     centre /= mVertices.size();
00162     for (unsigned j=0; j<mVertices.size(); j++)
00163     {
00164         VertexAndAngle<DIM> va;
00165         c_vector<double, DIM> centre_to_vertex = *(mVertices[j]) - centre;
00166 
00167         va.ComputeAndSetAngle(centre_to_vertex(0), centre_to_vertex(1));
00168         va.SetVertex(mVertices[j]);
00169         vertices_and_angles.push_back(va);
00170     }
00171 
00172     std::sort(vertices_and_angles.begin(), vertices_and_angles.end());
00173 
00174     // Create face
00175     mVertices.clear();
00176     for (typename std::vector<VertexAndAngle<DIM> >::iterator vertex_iterator = vertices_and_angles.begin();
00177          vertex_iterator !=vertices_and_angles.end();
00178          vertex_iterator++)
00179     {
00180         mVertices.push_back(vertex_iterator->GetVertex());
00181     }
00182 }
00183 
00184 template<unsigned DIM>
00185 void Face<DIM>::AddVertex(c_vector<double, DIM>* pVertex)
00186 {
00187     mVertices.push_back(pVertex);
00188 }   
00189 
00190 template<unsigned DIM>
00191 unsigned Face<DIM>::GetNumVertices()
00192 {
00193     return mVertices.size();
00194 }
00195 
00196 template<unsigned DIM>
00197 c_vector<double, DIM>& Face<DIM>::rGetVertex(unsigned index)
00198 {
00199     return *(mVertices[index]);
00200 }
00201 
00202 template<unsigned DIM>
00203 std::vector< c_vector<double, DIM>* >& Face<DIM>::rGetVertices()
00204 {
00205     return mVertices;
00206 }
00207 
00208 template<unsigned DIM>
00209 void Face<DIM>::SetVertex(unsigned index, c_vector<double, DIM>* pNewLocation)
00210 {
00211     mVertices[index] = pNewLocation;
00212 }
00213 
00215 // Explicit instantiation
00217 
00218 template class Face<1>;
00219 template class Face<2>;
00220 template class Face<3>;

Generated on Tue Aug 4 16:10:24 2009 for Chaste by  doxygen 1.5.5