2 #include "predicates.h"
5 #include <VolumeRemesher/numerics.h>
17 return vol_rem::interval_number(r.
to_double());
19 const double inf = std::numeric_limits<double>::max();
22 if (r < 0)
return vol_rem::interval_number(-std::nextafter(d, -inf), d);
23 if (r > 0)
return vol_rem::interval_number(-d, std::nextafter(d, inf));
24 return vol_rem::interval_number(0);
34 static MySingleton& instance()
36 static MySingleton instance;
43 MySingleton::instance();
47 bool is_rounded(
const Eigen::Ref<
const Eigen::Vector3<Rational>>& p)
49 return p[0].is_rounded() && p[1].is_rounded() && p[2].is_rounded();
51 bool is_rounded(
const Eigen::Ref<
const Eigen::Vector2<Rational>>& p)
53 return p[0].is_rounded() && p[1].is_rounded();
57 T determinant(
const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3>& mat)
59 assert(mat.rows() == mat.cols());
63 else if (mat.rows() == 2)
64 return mat(0, 0) * mat(1, 1) - mat(0, 1) * mat(1, 0);
65 else if (mat.rows() == 3)
66 return mat(0, 0) * (mat(1, 1) * mat(2, 2) - mat(1, 2) * mat(2, 1)) -
67 mat(0, 1) * (mat(1, 0) * mat(2, 2) - mat(1, 2) * mat(2, 0)) +
68 mat(0, 2) * (mat(1, 0) * mat(2, 1) - mat(1, 1) * mat(2, 0));
76 const Eigen::Ref<
const Eigen::Vector3<Rational>>& p0,
77 const Eigen::Ref<
const Eigen::Vector3<Rational>>& p1,
78 const Eigen::Ref<
const Eigen::Vector3<Rational>>& p2,
79 const Eigen::Ref<
const Eigen::Vector3<Rational>>& p3)
81 static bool initialized =
false;
87 if (is_rounded(p0) && is_rounded(p1) && is_rounded(p2) && is_rounded(p3)) {
95 Eigen::Vector3<vol_rem::interval_number> p0r_i;
96 Eigen::Vector3<vol_rem::interval_number> p1r_i;
97 Eigen::Vector3<vol_rem::interval_number> p2r_i;
98 Eigen::Vector3<vol_rem::interval_number> p3r_i;
100 vol_rem::setFPUModeToRoundUP();
101 for (int64_t i = 0; i < 3; ++i) {
107 Eigen::Matrix3<vol_rem::interval_number> M_i;
108 M_i.row(0) = p0r_i - p3r_i;
109 M_i.row(1) = p1r_i - p3r_i;
110 M_i.row(2) = p2r_i - p3r_i;
113 const auto det_i = determinant<vol_rem::interval_number>(M_i);
114 auto reliable = det_i.signIsReliable();
115 auto sign = det_i.sign();
116 vol_rem::setFPUModeToRoundNEAR();
123 Eigen::Vector3<Rational> p0r;
124 Eigen::Vector3<Rational> p1r;
125 Eigen::Vector3<Rational> p2r;
126 Eigen::Vector3<Rational> p3r;
128 for (int64_t i = 0; i < 3; ++i) {
135 Eigen::Matrix3<Rational> M;
136 M.row(0) = p0r - p3r;
137 M.row(1) = p1r - p3r;
138 M.row(2) = p2r - p3r;
141 for (
int i = 0; i < 3; ++i) {
142 for (
int j = 0; j < 3; ++j) {
143 assert(!M(i, j).is_rounded());
148 const auto det = determinant<Rational>(M);
156 const Eigen::Ref<
const Eigen::Vector3<double>>& p0,
157 const Eigen::Ref<
const Eigen::Vector3<double>>& p1,
158 const Eigen::Ref<
const Eigen::Vector3<double>>& p2,
159 const Eigen::Ref<
const Eigen::Vector3<double>>& p3)
167 const auto res = orient3d(p0nc.data(), p1nc.data(), p2nc.data(), p3nc.data());
178 int wmtk_orient2d(
double p0x,
double p0y,
double p1x,
double p1y,
double p2x,
double p2y)
181 double p0[2]{p0x, p0y};
182 double p1[2]{p1x, p1y};
183 double p2[2]{p2x, p2y};
184 const auto res = orient2d(p0, p1, p2);
195 const Eigen::Ref<
const Eigen::Vector2<Rational>>& p0,
196 const Eigen::Ref<
const Eigen::Vector2<Rational>>& p1,
197 const Eigen::Ref<
const Eigen::Vector2<Rational>>& p2)
199 if (is_rounded(p0) && is_rounded(p1) && is_rounded(p2)) {
200 return wmtk_orient2d(p0.cast<
double>(), p1.cast<
double>(), p2.cast<
double>());
204 Eigen::Vector2<vol_rem::interval_number> p0r_i;
205 Eigen::Vector2<vol_rem::interval_number> p1r_i;
206 Eigen::Vector2<vol_rem::interval_number> p2r_i;
208 vol_rem::setFPUModeToRoundUP();
209 for (int64_t i = 0; i < 2; ++i) {
215 Eigen::Matrix2<vol_rem::interval_number> M_i;
216 M_i.row(0) = p1r_i - p0r_i;
217 M_i.row(1) = p2r_i - p0r_i;
219 const auto det_i = determinant<vol_rem::interval_number>(M_i);
220 auto reliable = det_i.signIsReliable();
221 auto sign = det_i.sign();
222 vol_rem::setFPUModeToRoundNEAR();
229 Eigen::Vector2<Rational> p0r;
230 Eigen::Vector2<Rational> p1r;
231 Eigen::Vector2<Rational> p2r;
233 for (int64_t i = 0; i < 2; ++i) {
239 Eigen::Matrix2<Rational> M;
240 M.row(0) = p1r - p0r;
241 M.row(1) = p2r - p0r;
242 const auto det = determinant<Rational>(M);
248 const Eigen::Ref<
const Eigen::Vector2<double>>& p0,
249 const Eigen::Ref<
const Eigen::Vector2<double>>& p1,
250 const Eigen::Ref<
const Eigen::Vector2<double>>& p2)
252 Eigen::Vector2d p0nc = p0;
253 Eigen::Vector2d p1nc = p1;
254 Eigen::Vector2d p2nc = p2;
257 const auto res = orient2d(p0nc.data(), p1nc.data(), p2nc.data());
269 return p0 == p1 ? 0 : (p0 < p1 ? -1 : 1);
274 return p0 == p1 ? 0 : (p0 < p1 ? -1 : 1);
wmtk::Rational det(const wmtk::Vector2r &a, const wmtk::Vector2r &b)
int wmtk_orient3d(const Eigen::Ref< const Eigen::Vector3< Rational >> &p0, const Eigen::Ref< const Eigen::Vector3< Rational >> &p1, const Eigen::Ref< const Eigen::Vector3< Rational >> &p2, const Eigen::Ref< const Eigen::Vector3< Rational >> &p3)
int wmtk_orient1d(const Rational &p0, const Rational &p1)
vol_rem::interval_number rational_to_interval(const Rational &r)
int wmtk_orient2d(double p0x, double p0y, double p1x, double p1y, double p2x, double p2y)
Vector< double, 3 > Vector3d