[geometry] Finetuned robustness fixes of this weekend and fixed (again) for case #ggl_list_20110820_christophe

[SVN r77308]
This commit is contained in:
Barend Gehrels
2012-03-11 20:37:51 +00:00
parent 4efe4f0eb1
commit bad5e628ac
3 changed files with 38 additions and 7 deletions

View File

@@ -589,14 +589,15 @@ struct collinear : public base_turn_handler
if (side_pk != side_p || side_qk != side_q)
{
//std::cout << " -> Collinear "
//std::cout << "ROBUSTNESS -> Collinear "
// << " arr: " << arrival
// << " prod: " << product
// << " dir: " << side_p << " " << side_q
// << " rev: " << side_pk << " " << side_qk
// << std::endl;
handle_robustness(ti, product, side_p, side_q, side_pk, side_qk);
handle_robustness(ti, arrival, product,
side_p, side_q, side_pk, side_qk);
}
else
{
@@ -607,16 +608,19 @@ struct collinear : public base_turn_handler
}
static inline void handle_robustness(TurnInfo& ti,
int product,
int arrival, int product,
int side_p, int side_q,
int side_pk, int side_qk)
{
bool take_ui = product == 1;
if ((product == 1 && side_p == 1 && side_pk != 1)
|| (product == -1 && side_q == 1 && side_qk != 1))
if (product == arrival)
{
//std::cout << " -> Reverse" << std::endl;
take_ui = ! take_ui;
if ((product == 1 && side_p == 1 && side_pk != 1)
|| (product == -1 && side_q == 1 && side_qk != 1))
{
//std::cout << "ROBUSTNESS: -> Reverse" << std::endl;
take_ui = ! take_ui;
}
}
ui_else_iu(take_ui, ti);

View File

@@ -203,6 +203,26 @@ struct relate_cartesian_segments
promoted_type const zero = 0;
promoted_type const one = 1;
promoted_type const epsilon = std::numeric_limits<double>::epsilon();
if (sides.crossing() && math::abs(da-d) < 0.1)
{
// ROBUSTNESS: the r value can in epsilon-cases be 1.14, while (with perfect arithmetic)
// it should be one. If segments are crossing (we can see that with the sides)
// and one is inside the other, there must be an intersection point.
// We correct for that.
// TODO: find more cases (this only solves case called ggl_list_20110820_christophe in unit tests
if (r > one)
{
// std::cout << "ROBUSTNESS: correction of r " << r << std::endl;
r = one;
}
else if (r < zero)
{
// std::cout << "ROBUSTNESS: correction of r " << r << std::endl;
r = zero;
}
}
if (r < zero)
{
if (r < -epsilon)

View File

@@ -67,6 +67,13 @@ public :
&& sides[1].second == 0;
}
inline bool crossing() const
{
return sides[0].first * sides[0].second == -1
&& sides[1].first * sides[1].second == -1;
}
template <int Which>
inline bool zero() const
{