GEODE_COLD GEODE_PURE static inline bool triangle_oriented_sentinels(Perturbed2 x0, Perturbed2 x1, Perturbed2 x2) { // Move large sentinels last bool parity = 0; COMPARATOR(0,1) COMPARATOR(1,2) COMPARATOR(0,1) // Triangle orientation tests reduce to segment vs. direction and direction vs. direction when infinities are involved return parity ^ (!is_sentinel(x1) ? segment_to_direction_oriented(x0,x1,x2) // one sentinel : directions_oriented( x1,x2)); // two or three sentinels }
// Test whether an edge containing sentinels is Delaunay GEODE_COLD GEODE_PURE static inline bool is_delaunay_sentinels(Perturbed2 x0, Perturbed2 x1, Perturbed2 x2, Perturbed2 x3) { // Unfortunately, the sentinels need to be at infinity for purposes of Delaunay testing, and our SOS predicates // don't support infinities. Therefore, we need some case analysis. First, we move all the sentinels to the end, // sorted in decreasing order of index. Different sentinels will be placed at different orders of infinity, // with earlier indices further away, so our order will place larger infinities last. bool parity = 0; COMPARATOR(0,1) COMPARATOR(2,3) COMPARATOR(0,2) COMPARATOR(1,3) COMPARATOR(1,2) if (!is_sentinel(x2)) // One infinity: A finite circle contains infinity iff it is inside out, so we reduce to an orientation test return parity^triangle_oriented(x0,x1,x2); else if (!is_sentinel(x1)) // Two infinities: also an orientation test, but with the last point at infinity return parity^segment_to_direction_oriented(x0,x1,x2); else // Three infinities: the finite point no longer matters. return parity^directions_oriented(x1,x2); }
void EXPR_TAIL(void){ /*expr_tail = comparator simpexpr | epsilon*/ switch(l){ case EQ: case NEQ: case LEQ: case GEQ: case LSS: case GRT: COMPARATOR(); SIMPEXPR(); return; case ')': case ';': case ',' /*follow(EXPR_TAIL)*/: return; default: StdError(__func__); } }