volume.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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 "volume.h"
  9. #include "cross.h"
  10. #include <Eigen/Geometry>
  11. template <
  12. typename DerivedV,
  13. typename DerivedT,
  14. typename Derivedvol>
  15. IGL_INLINE void igl::volume(
  16. const Eigen::PlainObjectBase<DerivedV>& V,
  17. const Eigen::PlainObjectBase<DerivedT>& T,
  18. Eigen::PlainObjectBase<Derivedvol>& vol)
  19. {
  20. using namespace Eigen;
  21. const int m = T.rows();
  22. vol.resize(m,1);
  23. for(int t = 0;t<m;t++)
  24. {
  25. const RowVector3d & a = V.row(T(t,0));
  26. const RowVector3d & b = V.row(T(t,1));
  27. const RowVector3d & c = V.row(T(t,2));
  28. const RowVector3d & d = V.row(T(t,3));
  29. vol(t) = -(a-d).dot((b-d).cross(c-d))/6.;
  30. }
  31. }
  32. template <
  33. typename DerivedA,
  34. typename DerivedB,
  35. typename DerivedC,
  36. typename DerivedD,
  37. typename Derivedvol>
  38. IGL_INLINE void igl::volume(
  39. const Eigen::PlainObjectBase<DerivedA> & A,
  40. const Eigen::PlainObjectBase<DerivedB> & B,
  41. const Eigen::PlainObjectBase<DerivedC> & C,
  42. const Eigen::PlainObjectBase<DerivedD> & D,
  43. Eigen::PlainObjectBase<Derivedvol> & vol)
  44. {
  45. const auto & AmD = A-D;
  46. const auto & BmD = B-D;
  47. const auto & CmD = C-D;
  48. DerivedA BmDxCmD;
  49. cross(BmD.eval(),CmD.eval(),BmDxCmD);
  50. const auto & AmDdx = (AmD.array() * BmDxCmD.array()).rowwise().sum();
  51. vol = -AmDdx/6.;
  52. }
  53. template <
  54. typename VecA,
  55. typename VecB,
  56. typename VecC,
  57. typename VecD>
  58. IGL_INLINE typename VecA::Scalar igl::volume_single(
  59. const VecA & a,
  60. const VecB & b,
  61. const VecC & c,
  62. const VecD & d)
  63. {
  64. return -(a-d).dot((b-d).cross(c-d))/6.;
  65. }
  66. template <
  67. typename DerivedL,
  68. typename Derivedvol>
  69. IGL_INLINE void igl::volume(
  70. const Eigen::PlainObjectBase<DerivedL>& L,
  71. Eigen::PlainObjectBase<Derivedvol>& vol)
  72. {
  73. using namespace Eigen;
  74. const int m = L.rows();
  75. typedef typename Derivedvol::Scalar ScalarS;
  76. vol.resize(m,1);
  77. for(int t = 0;t<m;t++)
  78. {
  79. const ScalarS u = L(t,0);
  80. const ScalarS v = L(t,1);
  81. const ScalarS w = L(t,2);
  82. const ScalarS U = L(t,3);
  83. const ScalarS V = L(t,4);
  84. const ScalarS W = L(t,5);
  85. const ScalarS X = (w - U + v)*(U + v + w);
  86. const ScalarS x = (U - v + w)*(v - w + U);
  87. const ScalarS Y = (u - V + w)*(V + w + u);
  88. const ScalarS y = (V - w + u)*(w - u + V);
  89. const ScalarS Z = (v - W + u)*(W + u + v);
  90. const ScalarS z = (W - u + v)*(u - v + W);
  91. const ScalarS a = sqrt(x*Y*Z);
  92. const ScalarS b = sqrt(y*Z*X);
  93. const ScalarS c = sqrt(z*X*Y);
  94. const ScalarS d = sqrt(x*y*z);
  95. vol(t) = sqrt(
  96. (-a + b + c + d)*
  97. ( a - b + c + d)*
  98. ( a + b - c + d)*
  99. ( a + b + c - d))/
  100. (192.*u*v*w);
  101. }
  102. }
  103. #ifdef IGL_STATIC_LIBRARY
  104. // Explicit template specialization
  105. // generated by autoexplicit.sh
  106. template void igl::volume<Eigen::Matrix<double, -1, 6, 0, -1, 6>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 6, 0, -1, 6> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
  107. template Eigen::Matrix<double, 1, 3, 1, 1, 3>::Scalar igl::volume_single<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&);
  108. template Eigen::Matrix<double, 3, 1, 0, 3, 1>::Scalar igl::volume_single<Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::Matrix<double, 3, 1, 0, 3, 1> const&, Eigen::Matrix<double, 3, 1, 0, 3, 1> const&, Eigen::Matrix<double, 3, 1, 0, 3, 1> const&, Eigen::Matrix<double, 3, 1, 0, 3, 1> const&);
  109. template void igl::volume<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
  110. template void igl::volume<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 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, -1, 1, 0, -1, 1> >&);
  111. #endif