You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

97 lines
2.9 KiB

#include <implicit_point.h>
#pragma intrinsic(fabs)
int diff_det2_filtered(double p0, double p1, double q0, double q1, double r0, double r1)
{
double a_ = q0 - p0;
double b_ = q1 - p1;
double c_ = r0 - p0;
double d_ = r1 - p1;
double ad = a_ * d_;
double bc = b_ * c_;
double result = ad - bc;
double _tmp_fabs;
double max_var = 0.0;
if ((_tmp_fabs = fabs(a_)) > max_var) max_var = _tmp_fabs;
if ((_tmp_fabs = fabs(b_)) > max_var) max_var = _tmp_fabs;
if ((_tmp_fabs = fabs(c_)) > max_var) max_var = _tmp_fabs;
if ((_tmp_fabs = fabs(d_)) > max_var) max_var = _tmp_fabs;
double epsilon = max_var;
epsilon *= epsilon;
epsilon *= 8.881784197001253e-16;
if (result > epsilon) return IP_Sign::POSITIVE;
if (-result > epsilon) return IP_Sign::NEGATIVE;
return Filtered_Sign::UNCERTAIN;
}
int diff_det2_interval(interval_number p0,
interval_number p1,
interval_number q0,
interval_number q1,
interval_number r0,
interval_number r1)
{
setFPUModeToRoundUP();
interval_number a_(q0 - p0);
interval_number b_(q1 - p1);
interval_number c_(r0 - p0);
interval_number d_(r1 - p1);
interval_number ad(a_ * d_);
interval_number bc(b_ * c_);
interval_number result(ad - bc);
setFPUModeToRoundNEAR();
if (!result.signIsReliable()) return Filtered_Sign::UNCERTAIN;
return result.sign();
}
int diff_det2_exact(double p0, double p1, double q0, double q1, double r0, double r1)
{
expansionObject o;
double a_[2];
o.two_Diff(q0, p0, a_);
double b_[2];
o.two_Diff(q1, p1, b_);
double c_[2];
o.two_Diff(r0, p0, c_);
double d_[2];
o.two_Diff(r1, p1, d_);
double ad[8];
int ad_len = o.Gen_Product(2, a_, 2, d_, ad);
double bc[8];
int bc_len = o.Gen_Product(2, b_, 2, c_, bc);
double result[16];
int result_len = o.Gen_Diff(ad_len, ad, bc_len, bc, result);
double return_value = result[result_len - 1];
if (return_value > 0) return IP_Sign::POSITIVE;
if (return_value < 0) return IP_Sign::NEGATIVE;
if (return_value == 0) return IP_Sign::ZERO;
return IP_Sign::UNDEFINED;
}
int diff_det2(double p0, double p1, double q0, double q1, double r0, double r1)
{
int ret;
#ifdef IMPLICIT_PREDICATES_STAGE_STATS
semi_static_filter_stage++;
#endif
ret = diff_det2_filtered(p0, p1, q0, q1, r0, r1);
if (ret != Filtered_Sign::UNCERTAIN) return ret;
#ifdef IMPLICIT_PREDICATES_STAGE_STATS
interval_arithmetic_stage++;
#endif
ret = diff_det2_interval(p0, p1, q0, q1, r0, r1);
if (ret != Filtered_Sign::UNCERTAIN) return ret;
#ifdef IMPLICIT_PREDICATES_STAGE_STATS
exact_computation_stage++;
#endif
return diff_det2_exact(p0, p1, q0, q1, r0, r1);
}