// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2014 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 "centroid.h" #include template < typename DerivedV, typename DerivedF, typename Derivedc, typename Derivedvol> IGL_INLINE void igl::centroid( const Eigen::MatrixBase& V, const Eigen::MatrixBase& F, Eigen::PlainObjectBase& cen, Derivedvol & vol) { assert(F.cols() == 3 && "F should contain triangles."); assert(V.cols() == 3 && "V should contain 3d points."); const int m = F.rows(); // static assert that cen is either a 3d rowvector a 3d vector or a variable // size vector static_assert(Derivedc::IsVectorAtCompileTime,"cen should be a vector"); static_assert( Derivedc::RowsAtCompileTime == 3 || Derivedc::RowsAtCompileTime == -1 || Derivedc::ColsAtCompileTime == 3 || Derivedc::ColsAtCompileTime == -1, "cen should be sizeable to 3 vector"); cen.setZero(3); vol = 0; // loop over faces for(int f = 0;f RowVector3S; const RowVector3S & a = V.row(F(f,0)); const RowVector3S & b = V.row(F(f,1)); const RowVector3S & c = V.row(F(f,2)); // un-normalized normal const RowVector3S & n = (b-a).cross(c-a); // total volume via divergence theorem: ∫ 1 vol += n.dot(a)/6.; // centroid via divergence theorem and midpoint quadrature: ∫ x cen.array() += (1./24.*n.array()*((a+b).array().square() + (b+c).array().square() + (c+a).array().square()).array()); } cen *= 1./(2.*vol); } template < typename DerivedV, typename DerivedF, typename Derivedc> IGL_INLINE void igl::centroid( const Eigen::MatrixBase& V, const Eigen::MatrixBase& F, Eigen::PlainObjectBase& c) { typename Derivedc::Scalar vol; return centroid(V,F,c,vol); } #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation // generated by autoexplicit.sh template void igl::centroid, Eigen::Matrix, Eigen::Matrix, double>(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&, double&); template void igl::centroid, Eigen::Matrix, Eigen::Matrix, double>(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&, double&); // generated by autoexplicit.sh template void igl::centroid, Eigen::Matrix, Eigen::Matrix, float>(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&, float&); // generated by autoexplicit.sh template void igl::centroid, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::centroid, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&); template void igl::centroid, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&); template void igl::centroid, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&); template void igl::centroid, Eigen::Matrix, Eigen::Matrix>(Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, Eigen::PlainObjectBase>&); #endif