14#include <lagrange/MeshTrait.h>
24template <
typename Scalar,
int _Rows,
int _Cols>
26 const Eigen::Matrix<Scalar, _Rows, _Cols>& v1,
27 const Eigen::Matrix<Scalar, _Rows, _Cols>& v2)
29 static_assert((_Rows == 1 && _Cols == 3) || (_Rows == 3 && _Cols == 1),
"");
31 if (dot < -1)
return Scalar(-1.0);
32 if (dot > 1)
return Scalar(1.0);
37template <
typename Scalar,
int _Rows,
int _Cols>
39 const Eigen::Matrix<Scalar, _Rows, _Cols>& v1,
40 const Eigen::Matrix<Scalar, _Rows, _Cols>& v2)
42 static_assert((_Rows == 1 && _Cols == 3) || (_Rows == 3 && _Cols == 1),
"");
43 return std::atan2(v1.cross(v2).norm(), v1.dot(v2));
49template <
typename Scalar,
int _Rows,
int _Cols>
51 const Eigen::Matrix<Scalar, _Rows, _Cols>& v1,
52 const Eigen::Matrix<Scalar, _Rows, _Cols>& v2)
54 static_assert((_Rows == 1 && _Cols == 3) || (_Rows == 3 && _Cols == 1),
"");
55 return v1.dot(v2) * v2;
60template <
typename Scalar,
int _Rows,
int _Cols>
62 const Eigen::Matrix<Scalar, _Rows, _Cols>& v,
63 const Eigen::Matrix<Scalar, _Rows, _Cols>& n)
65 static_assert((_Rows == 1 && _Cols == 3) || (_Rows == 3 && _Cols == 1),
"");
71template <
typename Scalar,
int _Rows,
int _Cols>
73 const Eigen::Matrix<Scalar, _Rows, _Cols>& v1,
74 const Eigen::Matrix<Scalar, _Rows, _Cols>& v2,
75 const Eigen::Matrix<Scalar, _Rows, _Cols>& n)
77 static_assert((_Rows == 1 && _Cols == 3) || (_Rows == 3 && _Cols == 1),
"");
78 const Eigen::Matrix<Scalar, _Rows, _Cols> proj1 =
project_on_plane(v1, n).stableNormalized();
79 const Eigen::Matrix<Scalar, _Rows, _Cols> proj2 =
project_on_plane(v2, n).stableNormalized();
85template <
typename Scalar,
int _Rows,
int _Cols>
87 const Eigen::Matrix<Scalar, _Rows, _Cols>& v1,
88 const Eigen::Matrix<Scalar, _Rows, _Cols>& v2,
89 const Eigen::Matrix<Scalar, _Rows, _Cols>& n)
91 static_assert((_Rows == 1 && _Cols == 3) || (_Rows == 3 && _Cols == 1),
"");
94 return std::atan2(proj1.cross(proj2).norm(), proj1.dot(proj2));
105template <
typename MeshType>
106auto vector_between(
const MeshType& mesh,
typename MeshType::Index v1,
typename MeshType::Index v2)
108 static_assert(MeshTrait<MeshType>::is_mesh(),
"MeshType is not a mesh");
109 return mesh.get_vertices().row(v2) - mesh.get_vertices().row(v1);
121template <
typename Scalar>
123 const Eigen::Matrix<Scalar, 3, 1>& x,
124 Eigen::Matrix<Scalar, 3, 1>& y,
125 Eigen::Matrix<Scalar, 3, 1>& z)
128 x.array().abs().minCoeff(&imin);
129 Eigen::Matrix<Scalar, 3, 1> u;
130 for (
int i = 0, s = -1; i < 3; ++i) {
142 z = x.cross(u).stableNormalized();
143 y = z.cross(x).stableNormalized();
156template <
typename Scalar>
158 const Eigen::Vector3<Scalar>& p1,
159 const Eigen::Vector3<Scalar>& p2,
160 const Eigen::Vector3<Scalar>& p3)
163 Eigen::Matrix<Scalar, 3, 1> a = p2 - p1;
164 Eigen::Matrix<Scalar, 3, 1> b = p3 - p1;
167 Eigen::Matrix<Scalar, 3, 1> n = a.cross(b);
168 Scalar n_norm2 = n.squaredNorm();
171 if (n_norm2 < std::numeric_limits<Scalar>::epsilon())
return (p1 + p2 + p3) /
Scalar(3);
175 Eigen::Matrix<Scalar, 3, 1> term1 = a.squaredNorm() * (b.cross(n));
176 Eigen::Matrix<Scalar, 3, 1> term2 = b.squaredNorm() * (n.cross(a));
177 Eigen::Matrix<Scalar, 3, 1> circumcenter = p1 + (term1 + term2) / (
Scalar(2) * n_norm2);
@ Scalar
Mesh attribute must have exactly 1 channel.
Definition AttributeFwd.h:56
Main namespace for Lagrange.
void orthogonal_frame(const Eigen::Matrix< Scalar, 3, 1 > &x, Eigen::Matrix< Scalar, 3, 1 > &y, Eigen::Matrix< Scalar, 3, 1 > &z)
Build an orthogonal frame given a single vector.
Definition geometry3d.h:122
Scalar projected_cos_angle_between(const Eigen::Matrix< Scalar, _Rows, _Cols > &v1, const Eigen::Matrix< Scalar, _Rows, _Cols > &v2, const Eigen::Matrix< Scalar, _Rows, _Cols > &n)
Returns the angle between the vectors v1 and v2 projected on the plane defined by its normal n.
Definition geometry3d.h:72
Scalar projected_angle_between(const Eigen::Matrix< Scalar, _Rows, _Cols > &v1, const Eigen::Matrix< Scalar, _Rows, _Cols > &v2, const Eigen::Matrix< Scalar, _Rows, _Cols > &n)
Returns the angle between the vectors v1 and v2 projected on the plane defined by its normal n.
Definition geometry3d.h:86
Eigen::Vector3< Scalar > triangle_circumcenter_3d(const Eigen::Vector3< Scalar > &p1, const Eigen::Vector3< Scalar > &p2, const Eigen::Vector3< Scalar > &p3)
Returns the circumcenter of a 3D triangle.
Definition geometry3d.h:157
Eigen::Matrix< Scalar, _Rows, _Cols > project_on_plane(const Eigen::Matrix< Scalar, _Rows, _Cols > &v, const Eigen::Matrix< Scalar, _Rows, _Cols > &n)
Project the vector on the plane defined by its normal n.
Definition geometry3d.h:61
auto vector_between(const MeshType &mesh, typename MeshType::Index v1, typename MeshType::Index v2)
Returns the vector from v1 to v2.
Definition geometry3d.h:106
Eigen::Matrix< Scalar, _Rows, _Cols > project_on_line(const Eigen::Matrix< Scalar, _Rows, _Cols > &v1, const Eigen::Matrix< Scalar, _Rows, _Cols > &v2)
Project the vector v1 on the line defined by its vector v2.
Definition geometry3d.h:50
Scalar cos_angle_between(const Eigen::Matrix< Scalar, _Rows, _Cols > &v1, const Eigen::Matrix< Scalar, _Rows, _Cols > &v2)
Returns the cosine of the angle between two 3d vectors.
Definition geometry3d.h:25
Scalar angle_between(const Eigen::Matrix< Scalar, _Rows, _Cols > &v1, const Eigen::Matrix< Scalar, _Rows, _Cols > &v2)
Returns the angle between two 3d vectors.
Definition geometry3d.h:38