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);
123template <
typename Scalar>
125 const Eigen::Matrix<Scalar, 3, 1>& x,
126 Eigen::Matrix<Scalar, 3, 1>& y,
127 Eigen::Matrix<Scalar, 3, 1>& z)
130 const Eigen::Matrix<Scalar, 3, 1> n = x.stableNormalized();
131 const Scalar sign = std::copysign(one, n.z());
133 const Scalar b = n.x() * n.y() * a;
134 y = Eigen::Matrix<Scalar, 3, 1>(one +
sign * n.x() * n.x() * a,
sign * b, -
sign * n.x());
135 z = Eigen::Matrix<Scalar, 3, 1>(b,
sign + n.y() * n.y() * a, -n.y());
148template <
typename Scalar>
150 const Eigen::Vector3<Scalar>& p1,
151 const Eigen::Vector3<Scalar>& p2,
152 const Eigen::Vector3<Scalar>& p3)
155 Eigen::Matrix<Scalar, 3, 1> a = p2 - p1;
156 Eigen::Matrix<Scalar, 3, 1> b = p3 - p1;
159 Eigen::Matrix<Scalar, 3, 1> n = a.cross(b);
160 Scalar n_norm2 = n.squaredNorm();
163 if (n_norm2 < std::numeric_limits<Scalar>::epsilon())
return (p1 + p2 + p3) /
Scalar(3);
167 Eigen::Matrix<Scalar, 3, 1> term1 = a.squaredNorm() * (b.cross(n));
168 Eigen::Matrix<Scalar, 3, 1> term2 = b.squaredNorm() * (n.cross(a));
169 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:124
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:149
int sign(T val)
Get the sign of the value Returns either -1, 0, or 1.
Definition utils.h:44
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