Program Listing for File WindingNumbers.cpp
↰ Return to documentation for file (SPlisHSPlasH/Utilities/WindingNumbers.cpp)
#include "WindingNumbers.h"
#include "SPlisHSPlasH/Common.h"
#include <Eigen/Dense>
#define _USE_MATH_DEFINES
#include "math.h"
using namespace Utilities;
using namespace SPH;
using namespace Eigen;
Real WindingNumbers::computeGeneralizedWindingNumber(const Vector3r& p_, const Vector3r& a_, const Vector3r& b_, const Vector3r& c_)
{
const Vector3r& a = a_ - p_;
const Vector3r& b = b_ - p_;
const Vector3r& c = c_ - p_;
const Real normA = a.norm();
const Real normB = b.norm();
const Real normC = c.norm();
Matrix3r A;
A.row(0) = a;
A.row(1) = b;
A.row(2) = c;
const Real det = A.determinant();
const Real divisor = normA*normB*normC + (a.dot(b))*normC + (b.dot(c))*normA + (c.dot(a))*normB;
static const Real tau = 2.0 * M_PI;
return std::atan2(det,divisor) / tau; // Only divide by 2*pi instead of 4*pi because there was a 2 out front
}
Real WindingNumbers::computeGeneralizedWindingNumber(const Vector3r& p, const TriangleMesh& mesh)
{
const unsigned int *faces = mesh.getFaces().data();
const unsigned int nFaces = mesh.numFaces();
const Vector3r *v = mesh.getVertices().data();
// compute generalized winding number
Real w_p = 0;
#pragma omp parallel for reduction (+: w_p)
for (int idx = 0; idx < static_cast<int>(nFaces); idx ++)
{
const Vector3r& a = v[faces[idx*3+0]];
const Vector3r& b = v[faces[idx*3+1]];
const Vector3r& c = v[faces[idx*3+2]];
w_p += computeGeneralizedWindingNumber(p, a, b, c);
}
return w_p;
}