// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2013 Alec Jacobson // // This Source Code Form is subject to the terms of the Mozilla Public License // v. 2.0. If a copy of the MPL was not distributed with this file, You can // obtain one at http://mozilla.org/MPL/2.0/. #include "doublearea.h" #include "edge_lengths.h" #include "sort.h" #include #include template IGL_INLINE void igl::doublearea( const Eigen::PlainObjectBase & V, const Eigen::PlainObjectBase & F, Eigen::PlainObjectBase & dblA) { const int dim = V.cols(); // Only support triangles assert(F.cols() == 3); const int m = F.rows(); // Compute edge lengths Eigen::PlainObjectBase l; // "Lecture Notes on Geometric Robustness" Shewchuck 09, Section 3.1 // http://www.cs.berkeley.edu/~jrs/meshpapers/robnotes.pdf switch(dim) { case 3: { dblA = Eigen::PlainObjectBase::Zero(m,1); for(int d = 0;d<3;d++) { Eigen::Matrix Vd(V.rows(),2); Vd << V.col(d), V.col((d+1)%3); Eigen::PlainObjectBase dblAd; doublearea(Vd,F,dblAd); dblA.array() += dblAd.array().square(); } dblA = dblA.array().sqrt().eval(); break; } case 2: { dblA.resize(m,1); for(int f = 0;f IGL_INLINE void igl::doublearea( const Eigen::PlainObjectBase & ul, Eigen::PlainObjectBase & dblA) { using namespace Eigen; using namespace std; // Only support triangles assert(ul.cols() == 3); // Number of triangles const int m = ul.rows(); Eigen::PlainObjectBase l; MatrixXi _; sort(ul,2,false,l,_); // semiperimeters Matrix s = l.rowwise().sum()*0.5; assert(s.rows() == m); // resize output dblA.resize(l.rows(),1); for(int i = 0;i=0); //dblA(i) = 2.0*sqrt(arg); // Kahan's Heron's formula const typename Derivedl::Scalar arg = (l(i,0)+(l(i,1)+l(i,2)))* (l(i,2)-(l(i,0)-l(i,1)))* (l(i,2)+(l(i,0)-l(i,1)))* (l(i,0)+(l(i,1)-l(i,2))); dblA(i) = 2.0*0.25*sqrt(arg); assert( l(i,2) - (l(i,0)-l(i,1)) && "FAILED KAHAN'S ASSERTION"); assert(dblA(i) == dblA(i) && "DOUBLEAREA() PRODUCED NaN"); } } #ifndef IGL_HEADER_ONLY // Explicit template specialization // generated by autoexplicit.sh template void igl::doublearea, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase >&); template void igl::doublearea, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase >&); template void igl::doublearea, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase >&); template void igl::doublearea, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase >&); #endif