Wildmeshing Toolkit
Loading...
Searching...
No Matches
predicates.hpp
1#pragma once
2
3#include <Eigen/Core>
4
5namespace wmtk::utils::predicates {
6
14enum class Orientation {
15 POSITIVE = 1,
16 INSIDE = 1,
17 NEGATIVE = -1,
18 OUTSIDE = -1,
19 COLLINEAR = 0,
20 COPLANAR = 0,
21 COCIRCULAR = 0,
22 COSPHERICAL = 0,
23 DEGENERATE = 0
24};
25
26namespace detail {
27
47int orient2d_sign(double ax, double ay, double bx, double by, double cx, double cy);
48int orient3d_sign(
49 double ax,
50 double ay,
51 double az,
52 double bx,
53 double by,
54 double bz,
55 double cx,
56 double cy,
57 double cz,
58 double dx,
59 double dy,
60 double dz);
61
62inline Orientation from_sign(const int s)
63{
64 return s > 0 ? Orientation::POSITIVE : (s < 0 ? Orientation::NEGATIVE : Orientation::COLLINEAR);
65}
66
67} // namespace detail
68
77inline void exactinit() {}
78
85template <typename D0, typename D1, typename D2>
86inline Orientation orient2d(
87 const Eigen::MatrixBase<D0>& a,
88 const Eigen::MatrixBase<D1>& b,
89 const Eigen::MatrixBase<D2>& c)
90{
91 return detail::from_sign(detail::orient2d_sign(a[0], a[1], b[0], b[1], c[0], c[1]));
92}
93
106template <typename D0, typename D1, typename D2, typename D3>
107inline Orientation orient3d(
108 const Eigen::MatrixBase<D0>& a,
109 const Eigen::MatrixBase<D1>& b,
110 const Eigen::MatrixBase<D2>& c,
111 const Eigen::MatrixBase<D3>& d)
112{
113 return detail::from_sign(
114 detail::
115 orient3d_sign(a[0], a[1], a[2], b[0], b[1], b[2], c[0], c[1], c[2], d[0], d[1], d[2]));
116}
117
121template <typename D0, typename D1, typename D2>
122inline bool is_degenerate(
123 const Eigen::MatrixBase<D0>& v0,
124 const Eigen::MatrixBase<D1>& v1,
125 const Eigen::MatrixBase<D2>& v2)
126{
127 if constexpr (Eigen::MatrixBase<D0>::RowsAtCompileTime == 3) {
128 // Three points in 3D are collinear only if they are collinear in all three
129 // coordinate-plane projections; any one projection can flatten a real triangle.
130 for (int dim = 0; dim < 3; ++dim) {
131 const Eigen::Vector2d p0(v0[dim], v0[(dim + 1) % 3]);
132 const Eigen::Vector2d p1(v1[dim], v1[(dim + 1) % 3]);
133 const Eigen::Vector2d p2(v2[dim], v2[(dim + 1) % 3]);
134 if (orient2d(p0, p1, p2) != Orientation::COLLINEAR) {
135 return false;
136 }
137 }
138 return true;
139 } else {
140 return orient2d(v0, v1, v2) == Orientation::COLLINEAR;
141 }
142}
143
147template <typename D0, typename D1, typename D2, typename D3>
148inline bool is_degenerate(
149 const Eigen::MatrixBase<D0>& v0,
150 const Eigen::MatrixBase<D1>& v1,
151 const Eigen::MatrixBase<D2>& v2,
152 const Eigen::MatrixBase<D3>& v3)
153{
154 return orient3d(v0, v1, v2, v3) == Orientation::COPLANAR;
155}
156
157} // namespace wmtk::utils::predicates