centroid.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2014 Alec Jacobson <alecjacobson@gmail.com>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "centroid.h"
  9. #include <Eigen/Geometry>
  10. template <
  11. typename DerivedV,
  12. typename DerivedF,
  13. typename Derivedc,
  14. typename Derivedvol>
  15. IGL_INLINE void igl::centroid(
  16. const Eigen::PlainObjectBase<DerivedV>& V,
  17. const Eigen::PlainObjectBase<DerivedF>& F,
  18. Eigen::PlainObjectBase<Derivedc>& cen,
  19. Derivedvol & vol)
  20. {
  21. using namespace Eigen;
  22. assert(F.cols() == 3 && "F should contain triangles.");
  23. assert(V.cols() == 3 && "V should contain 3d points.");
  24. const int m = F.rows();
  25. cen.setZero();
  26. vol = 0;
  27. // loop over faces
  28. for(int f = 0;f<m;f++)
  29. {
  30. // "Calculating the volume and centroid of a polyhedron in 3d" [Nuernberg 2013]
  31. // http://www2.imperial.ac.uk/~rn/centroid.pdf
  32. // rename corners
  33. const RowVector3d & a = V.row(F(f,0));
  34. const RowVector3d & b = V.row(F(f,1));
  35. const RowVector3d & c = V.row(F(f,2));
  36. // un-normalized normal
  37. const RowVector3d & n = (b-a).cross(c-a);
  38. // total volume via divergence theorem: ∫ 1
  39. vol += n.dot(a)/6.;
  40. // centroid via divergence theorem and midpoint quadrature: ∫ x
  41. cen.array() += (1./24.*n.array()*((a+b).array().square() + (b+c).array().square() +
  42. (c+a).array().square()).array());
  43. }
  44. cen *= 1./(2.*vol);
  45. }
  46. template <
  47. typename DerivedV,
  48. typename DerivedF,
  49. typename Derivedc>
  50. IGL_INLINE void igl::centroid(
  51. const Eigen::PlainObjectBase<DerivedV>& V,
  52. const Eigen::PlainObjectBase<DerivedF>& F,
  53. Eigen::PlainObjectBase<Derivedc>& c)
  54. {
  55. typename Derivedc::Scalar vol;
  56. return centroid(V,F,c,vol);
  57. }
  58. #ifdef IGL_STATIC_LIBRARY
  59. template void igl::centroid<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >&);
  60. #endif