13 const Eigen::Vector3d& v0,
14 const Eigen::Vector3d& v1,
15 const Eigen::Vector3d& v2
18 if (!v0.allFinite() || !v1.allFinite() || !v2.allFinite()) {
19 return std::numeric_limits<double>::quiet_NaN();
23 Eigen::Vector3d centroid = (v0 + v1 + v2) / 3.0;
27 X.col(0) = v0 - centroid;
28 X.col(1) = v1 - centroid;
29 X.col(2) = v2 - centroid;
32 Eigen::Matrix3d
K = (X * X.transpose()) / 3.0;
35 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigensolver(
K);
36 if (eigensolver.info() != Eigen::Success) {
37 return std::numeric_limits<double>::quiet_NaN();
40 Eigen::Vector3d eigenvalues = eigensolver.eigenvalues();
43 std::sort(eigenvalues.data(), eigenvalues.data() + 3);
47 double lambda2 = eigenvalues(1);
48 double lambda3 = eigenvalues(2);
51 double denominator = lambda2 + lambda3;
52 if (std::abs(denominator) < 1e-12) {
56 double isotropy = 2.0 * lambda2 / denominator;
59 isotropy = std::max(0.0, std::min(1.0, isotropy));
65 const std::vector<int>& faces,
66 const std::vector<Eigen::Vector3d>& vertices
68 size_t nFaces = faces.size() / 3;
69 std::vector<double> isotropy(nFaces);
71 for (
size_t iface = 0; iface < nFaces; ++iface) {
72 int i0 = faces[iface * 3 + 0];
73 int i1 = faces[iface * 3 + 1];
74 int i2 = faces[iface * 3 + 2];
77 if (i0 < 0 || i0 >=
static_cast<int>(vertices.size()) ||
78 i1 < 0 || i1 >=
static_cast<int>(vertices.size()) ||
79 i2 < 0 || i2 >=
static_cast<int>(vertices.size())) {
80 isotropy[iface] = std::numeric_limits<double>::quiet_NaN();
84 const Eigen::Vector3d& v0 = vertices[i0];
85 const Eigen::Vector3d& v1 = vertices[i1];
86 const Eigen::Vector3d& v2 = vertices[i2];