3#include <Eigen/Geometry>
12 const Eigen::VectorXd &a,
13 const Eigen::VectorXd &b,
14 const Eigen::VectorXd &u)
16 using Eigen::Vector2d;
17 using Eigen::VectorXd;
19 const int dimensions = a.size();
20 PRECICE_ASSERT(dimensions == b.size(),
"A and B need to have the same dimensions.", dimensions, b.size());
21 PRECICE_ASSERT(dimensions == u.size(),
"A and the point need to have the same dimensions.", dimensions, u.size());
22 PRECICE_ASSERT((dimensions == 2) || (dimensions == 3), dimensions);
24 Vector2d barycentricCoords;
34 barycentricCoords(1) = au.dot(ab) / ab.dot(ab);
35 barycentricCoords(0) = 1 - barycentricCoords(1);
37 return barycentricCoords;
40static double crossProduct2D(
const Eigen::Vector2d &u,
const Eigen::Vector2d &v)
42 return u(0) * v(1) - u(1) * v(0);
46 const Eigen::VectorXd &a,
47 const Eigen::VectorXd &b,
48 const Eigen::VectorXd &c,
49 const Eigen::VectorXd &u)
51 using Eigen::Vector2d;
52 using Eigen::Vector3d;
54 const int dimensions = a.size();
55 PRECICE_ASSERT(dimensions == b.size(),
"A and B need to have the same dimensions.", dimensions, b.size());
56 PRECICE_ASSERT(dimensions == c.size(),
"A and C need to have the same dimensions.", dimensions, c.size());
57 PRECICE_ASSERT(dimensions == u.size(),
"A and the point need to have the same dimensions.", dimensions, u.size());
59 Vector3d barycentricCoords;
63 if (dimensions == 3) {
64 Vector3d ab, ac, au, n;
69 auto nDotN = n.dot(n);
70 PRECICE_ASSERT(nDotN != 0,
"It seems a degenerate triangle was sent.");
71 scaleFactor = 1.0 / nDotN;
76 barycentricCoords(2) = n.dot(ab.cross(au)) * scaleFactor;
77 barycentricCoords(1) = n.dot(au.cross(ac)) * scaleFactor;
78 barycentricCoords(0) = 1 - barycentricCoords(1) - barycentricCoords(2);
82 Vector2d ab, ac, ub, uc, ua;
90 PRECICE_ASSERT(twiceArea != 0,
"It seems a degenerate triangle was sent.");
91 scaleFactor = 1.0 / twiceArea;
95 barycentricCoords(2) = 1 - barycentricCoords(0) - barycentricCoords(1);
98 return barycentricCoords;
102 const Eigen::VectorXd &a,
103 const Eigen::VectorXd &b,
104 const Eigen::VectorXd &c,
105 const Eigen::VectorXd &d,
106 const Eigen::VectorXd &u)
108 using Eigen::Vector3d;
109 using Eigen::Vector4d;
111 const int dimensions = a.size();
114 PRECICE_ASSERT(dimensions == b.size(),
"A and B need to have the same dimensions.", dimensions, b.size());
115 PRECICE_ASSERT(dimensions == c.size(),
"A and C need to have the same dimensions.", dimensions, c.size());
116 PRECICE_ASSERT(dimensions == d.size(),
"A and D need to have the same dimensions.", dimensions, d.size());
117 PRECICE_ASSERT(dimensions == u.size(),
"A and the point need to have the same dimensions.", dimensions, u.size());
119 Vector4d barycentricCoords;
133 Vector3d abc = ab.cross(bc);
134 Vector3d abd = ab.cross(-ad);
135 Vector3d acd = ac.cross(ad);
137 auto volume = abc.dot(ad);
139 barycentricCoords(3) = abc.dot(au) / volume;
140 barycentricCoords(2) = abd.dot(du) / volume;
141 barycentricCoords(1) = acd.dot(cu) / volume;
142 barycentricCoords(0) = 1 - barycentricCoords(3) - barycentricCoords(2) - barycentricCoords(1);
144 return barycentricCoords;
#define PRECICE_ASSERT(...)
Provides operations to calculate barycentric coordinates for a point's projection onto a primitive.
static double crossProduct2D(const Eigen::Vector2d &u, const Eigen::Vector2d &v)
Eigen::Vector3d calcBarycentricCoordsForTriangle(const Eigen::VectorXd &a, const Eigen::VectorXd &b, const Eigen::VectorXd &c, const Eigen::VectorXd &u)
Eigen::Vector4d calcBarycentricCoordsForTetrahedron(const Eigen::VectorXd &a, const Eigen::VectorXd &b, const Eigen::VectorXd &c, const Eigen::VectorXd &d, const Eigen::VectorXd &u)
Eigen::Vector2d calcBarycentricCoordsForEdge(const Eigen::VectorXd &a, const Eigen::VectorXd &b, const Eigen::VectorXd &u)