Răsfoiți Sursa

support for 2d bary coords

Former-commit-id: 9c27aed94452d371e3559008f06b14a6dd577822
Alec Jacobson 11 ani în urmă
părinte
comite
aba141dec1

+ 35 - 0
include/igl/barycentric_coordinates.cpp

@@ -7,6 +7,7 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "barycentric_coordinates.h"
 #include "barycentric_coordinates.h"
 #include "volume.h"
 #include "volume.h"
+#include "doublearea.h"
 
 
 template <
 template <
   typename DerivedP,
   typename DerivedP,
@@ -47,6 +48,40 @@ IGL_INLINE void igl::barycentric_coordinates(
   L.array().colwise() /= vol.array();
   L.array().colwise() /= vol.array();
 }
 }
 
 
+template <
+  typename DerivedP,
+  typename DerivedA,
+  typename DerivedB,
+  typename DerivedC,
+  typename DerivedL>
+IGL_INLINE void igl::barycentric_coordinates(
+  const Eigen::PlainObjectBase<DerivedP> & P,
+  const Eigen::PlainObjectBase<DerivedA> & A,
+  const Eigen::PlainObjectBase<DerivedB> & B,
+  const Eigen::PlainObjectBase<DerivedC> & C,
+  Eigen::PlainObjectBase<DerivedL> & L)
+{
+  using namespace Eigen;
+  assert(P.cols() == 2 && "query must be in 2d");
+  assert(A.cols() == 2 && "corners must be in 2d");
+  assert(B.cols() == 2 && "corners must be in 2d");
+  assert(C.cols() == 2 && "corners must be in 2d");
+  assert(P.rows() == A.rows() && "Must have same number of queries as corners");
+  assert(A.rows() == B.rows() && "Corners must be same size");
+  assert(A.rows() == C.rows() && "Corners must be same size");
+  typedef Matrix<typename DerivedL::Scalar,DerivedL::RowsAtCompileTime,1> 
+    VectorXS;
+  // Total area
+  VectorXS dblA,LA,LB,LC;
+  doublearea(P,B,C,LA);
+  doublearea(A,P,C,LB);
+  doublearea(A,B,P,LC);
+  doublearea(A,B,C,dblA);
+  L.resize(P.rows(),3);
+  L<<LA,LB,LC;
+  L.array().colwise() /= dblA.array();
+}
+
 #ifndef IGL_HEADER_ONLY
 #ifndef IGL_HEADER_ONLY
 template void igl::barycentric_coordinates<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::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> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 template void igl::barycentric_coordinates<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::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> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 #endif
 #endif

+ 23 - 0
include/igl/barycentric_coordinates.h

@@ -36,6 +36,29 @@ namespace igl
     const Eigen::PlainObjectBase<DerivedC> & C,
     const Eigen::PlainObjectBase<DerivedC> & C,
     const Eigen::PlainObjectBase<DerivedD> & D,
     const Eigen::PlainObjectBase<DerivedD> & D,
     Eigen::PlainObjectBase<DerivedL> & L);
     Eigen::PlainObjectBase<DerivedL> & L);
+  // Compute barycentric coordinates in a triangle
+  //
+  // Inputs:
+  //   P  #P by 2 Query points in 2d
+  //   A  #P by 2 Triangle corners in 2d
+  //   B  #P by 2 Triangle corners in 2d
+  //   C  #P by 2 Triangle corners in 2d
+  // Outputs:
+  //   L  #P by e list of barycentric coordinates
+  //   
+  template <
+    typename DerivedP,
+    typename DerivedA,
+    typename DerivedB,
+    typename DerivedC,
+    typename DerivedL>
+  IGL_INLINE void barycentric_coordinates(
+    const Eigen::PlainObjectBase<DerivedP> & P,
+    const Eigen::PlainObjectBase<DerivedA> & A,
+    const Eigen::PlainObjectBase<DerivedB> & B,
+    const Eigen::PlainObjectBase<DerivedC> & C,
+    Eigen::PlainObjectBase<DerivedL> & L);
+
 }
 }
 
 
 #ifdef IGL_HEADER_ONLY
 #ifdef IGL_HEADER_ONLY

+ 21 - 0
include/igl/doublearea.cpp

@@ -60,6 +60,27 @@ IGL_INLINE void igl::doublearea(
   }
   }
 }
 }
 
 
+template <
+  typename DerivedA,
+  typename DerivedB,
+  typename DerivedC,
+  typename DerivedD>
+IGL_INLINE void doublearea( 
+  const Eigen::PlainObjectBase<DerivedA> & A, 
+  const Eigen::PlainObjectBase<DerivedB> & B, 
+  const Eigen::PlainObjectBase<DerivedC> & C,
+  Eigen::PlainObjectBase<DerivedD> & D)
+{
+  assert(A.cols() == 2 && "corners should be 2d");
+  assert(B.cols() == 2 && "corners should be 2d");
+  assert(C.cols() == 2 && "corners should be 2d");
+  assert(A.rows() == B.rows() && "corners should have same length");
+  assert(A.rows() == C.rows() && "corners should have same length");
+  const auto & R = A-C;
+  const auto & S = B-C;
+  D = R.col(0).array()*S.col(1).array() - R.col(1).array()*S.col(0).array();
+}
+
 template <
 template <
   typename DerivedA,
   typename DerivedA,
   typename DerivedB,
   typename DerivedB,

+ 11 - 0
include/igl/doublearea.h

@@ -31,6 +31,17 @@ namespace igl
     const Eigen::PlainObjectBase<DerivedV> & V, 
     const Eigen::PlainObjectBase<DerivedV> & V, 
     const Eigen::PlainObjectBase<DerivedF> & F, 
     const Eigen::PlainObjectBase<DerivedF> & F, 
     Eigen::PlainObjectBase<DeriveddblA> & dblA);
     Eigen::PlainObjectBase<DeriveddblA> & dblA);
+  // Stream of triangles
+  template <
+    typename DerivedA,
+    typename DerivedB,
+    typename DerivedC,
+    typename DerivedD>
+  IGL_INLINE void doublearea( 
+    const Eigen::PlainObjectBase<DerivedA> & A, 
+    const Eigen::PlainObjectBase<DerivedB> & B, 
+    const Eigen::PlainObjectBase<DerivedC> & C,
+    Eigen::PlainObjectBase<DerivedD> & D);
   // Single triangle in 2D!
   // Single triangle in 2D!
   //
   //
   // This should handle streams of corners not just single corners
   // This should handle streams of corners not just single corners