16#include <wmtk/utils/DisableWarnings.hpp>
17#include <igl/winding_number.h>
18#include <igl/WindingNumberAABB.h>
19#include <wmtk/utils/EnableWarnings.hpp>
22#include <wmtk/threading/parallel_for.hpp>
27namespace wmtk::utils {
42inline double signed_angle_2d(
double ax,
double ay,
double bx,
double by,
double px,
double py)
45 double o2A[2] = {px - ax, py - ay};
46 double o2B[2] = {px - bx, py - by};
49 for (
int i = 0; i < 2; i++) {
50 o2Al += o2A[i] * o2A[i];
51 o2Bl += o2B[i] * o2B[i];
53 o2Al = std::sqrt(o2Al);
54 o2Bl = std::sqrt(o2Bl);
56 for (
int i = 0; i < 2; i++) {
64 constexpr double two_pi = 2.0 * 3.14159265358979323846;
65 return -std::atan2(o2B[0] * o2A[1] - o2B[1] * o2A[0], o2B[0] * o2A[0] + o2B[1] * o2A[1]) /
79winding_number_2d_point(
const Eigen::MatrixXd& V,
const Eigen::MatrixXi& E,
double px,
double py)
82 for (Eigen::Index f = 0; f < E.rows(); ++f) {
83 const Eigen::Index a = E(f, 0);
84 const Eigen::Index b = E(f, 1);
85 w += detail::signed_angle_2d(V(a, 0), V(a, 1), V(b, 0), V(b, 1), px, py);
95inline void winding_number(
96 const Eigen::MatrixXd& V,
97 const Eigen::MatrixXi& F,
98 const Eigen::MatrixXd& O,
103 if (O.rows() == 0 || F.rows() == 0 || V.rows() == 0)
return;
106 igl::WindingNumberAABB<Eigen::Matrix<double, 1, 3>, Eigen::MatrixXd, Eigen::MatrixXi> hier(
113 threading::parallel_for(
114 threading::range(0,
static_cast<size_t>(O.rows())),
115 [&](
const threading::range& r) {
116 for (int o = r.begin(); o < r.end(); ++o) {
117 W(o) = hier.winding_number(O.row(o));
120 std::max(num_threads, 1));
141inline void winding_number_2d(
142 const Eigen::MatrixXd& V,
143 const Eigen::MatrixXi& E,
144 const Eigen::MatrixXd& O,
149 if (O.rows() == 0 || E.rows() == 0 || V.rows() == 0)
return;
151 threading::parallel_for(
152 threading::range(0,
static_cast<size_t>(O.rows())),
153 [&](
const threading::range& r) {
154 for (size_t o = r.begin(); o < r.end(); ++o) {
155 const Eigen::Index i = static_cast<Eigen::Index>(o);
156 W(i) = winding_number_2d_point(V, E, O(i, 0), O(i, 1));
159 std::max(num_threads, 1));