Skip to content

Commit

Permalink
Fix for Line_3 Ray_3 do_intersect (CGAL#8398)
Browse files Browse the repository at this point in the history
## Summary of Changes

Some non intersection is wrongfully detected as an intersection for the
Line_3 Ray_3 combination. Here is an illustration:


![image](https://github.com/user-attachments/assets/f18fd662-5ad6-4a01-9a49-a8d0c62cf7fe)

The base code is :
```cpp
  if(!do_intersect(l, r.supporting_line()))
    return false;

  typename K::Coplanar_orientation_3 pred = k.coplanar_orientation_3_object();
  CGAL::Orientation p0p1s = pred(l.point(0), l.point(1), r.source());
  if(p0p1s == COLLINEAR)
    return true;

  CGAL::Orientation stp0 = pred(r.source(), r.second_point(), l.point(0));
  if(stp0 == COLLINEAR)
    return Ray_3_has_on_collinear_Point_3(r,l.point(0),k);

  return (p0p1s != stp0);
```

The supporting line of the ray intersects the line, and then nothing is
collinear, so we check L0,L1,R1 vs R0,R1,L0, which are of opposite sign
so there is an intersection... but there is none.

This check is very similar to what is done in Ray_3-Ray_3, where it is
correct.

I did a naive fix for now: without loss of generality we can go to the
configuration below


![image](https://github.com/user-attachments/assets/5f004941-7f58-4bf3-8416-7dc2144a891f)

and so we have an intersection as long as the ray "points" in the other
slab wrt to the line. And so, in coplanar orientation checks, if the
orientation L0,L1,R0 differs from L0, L1, (L0 + (R1-R0)).

I feel like I could probably skip at least a translation by having
something like Coplanar_orientation(P3, P3, P3, V3), and maybe even
more...

## Release Management

* Affected package(s): `Intersections_3`
* Issue(s) solved (if any): -
* Feature/Small Feature (if any): -
* License and copyright ownership: no change
  • Loading branch information
sloriot authored Aug 26, 2024
2 parents 51c2cd9 + c1e5926 commit 9dea168
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,8 @@ do_intersect(const typename K::Line_3& l,
if(p0p1s == COLLINEAR)
return true;

CGAL::Orientation stp0 = pred(r.source(), r.second_point(), l.point(0));
if(stp0 == COLLINEAR)
return Ray_3_has_on_collinear_Point_3(r,l.point(0),k);

return (p0p1s != stp0);
typename K::Point_3 lst = l.point(0) + (r.point(1) - r.point(0));
return (pred(l.point(0), l.point(1), r.point(0), lst) != CGAL::POSITIVE);
}

template <class K>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,10 @@ struct Line_3_intersection_tester
check_no_intersection(L(p(0,0,0),p(1,0,0)), R(p(3,0,1),p(6,0,1)));
check_no_intersection(L(p(0,0,0),p(1,0,0)), R(p(0,2,0),p(0,4,0)));
check_no_intersection(L(p(0,0,0),p(1,0,0)), R(p(6,2,0),p(5,4,0)));
check_no_intersection(L(p(0,0,0),p(0,1,0)), R(p(1,-1,0),p(1,0,0)));
check_no_intersection(L(p(0,-10,0),p(0,-9,0)), R(p(1,-1,0),p(2,0,0)));
check_no_intersection(L(p(0,-10,0),p(0,0,0)), R(p(1,-1,0),p(2,0,0)));
check_no_intersection(L(p(0,0,0),p(0,1,0)), R(p(1,-1,0),p(2,0,0)));

// Point intersection
check_intersection (L(p(0,0,0),p(1,0,0)), R(p(3,0,0),p(6,4,0)),
Expand Down
12 changes: 12 additions & 0 deletions Intersections_3/test/Intersections_3/test_intersections_Ray_3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ struct Ray_3_intersection_tester
check_no_intersection (R(p(0,0,0), p(1,0,0)), R(p(0,1,0), p(0,2,0)));
check_no_intersection (R(p(0,0,0), p(1,0,0)), R(p(-1,0,0), p(-1,-1,0)));

check_no_intersection (R(p(1,-1,0), p(2,0,0)), R(p(2,-1,0), p(3,0,0)));
check_no_intersection (R(p(1,-1,0), p(2,0,0)), R(p(2,-1,0), p(3,-1,0)));
check_no_intersection (R(p(1,-1,0), p(2,0,0)), R(p(2,-1,0), p(3,-2,0)));
check_no_intersection (R(p(0,0,0), p(0,1,0)), R(p(0,-1,0), p(1,-1,0)));
check_no_intersection (R(p(0,0,0), p(0,1,0)), R(p(-1,-3,0),p(2,0,0)));
check_no_intersection (R(p(0,0,0), p(0,1,0)), R(p(-2,-4,0),p(-1,-3,0)));
check_no_intersection (R(p(0,0,0), p(0,1,0)), R(p(1,-1,0), p(2,0,0)));

// Point
check_intersection (R(p(0,0,0), p(1,0,0)), R(p(0,0,0), p(-1,0,0)),
p(0,0,0));
Expand All @@ -88,6 +96,10 @@ struct Ray_3_intersection_tester
check_intersection (R(p(0,0,0), p(1,0,0)), R(p(1,-2,0), p(1,-1,0)),
p(1,0,0));

check_intersection (R(p(0,0,0), p(1,0,0)), R(p(1,-2,0), p(1,-1,0)),
p(1,0,0));


// Segment
check_intersection (R(p(0,0,0), p(1,0,0)), R(p(2,0,0), p(-3,0,0)),
S(p(0,0,0), p(2,0,0)), false);
Expand Down

0 comments on commit 9dea168

Please sign in to comment.