I think I have discovered a bug in OCCT, but before reporting it further, I would like to make sure it is indeed a bug, so I appreciate that you read the following lines.

**Bug description:**

Geom2dAPI_InterCurveCurve and GeomAPI_ExtremaCurveCurve fail to detect intersection between a circumference and a line segment, when the line segment endpoint is on the circumference AND the line is tangent to the circumference. It successfully finds the intersection if the line is NOT tangent (maintaining the point on the circunference the same).

This originated from tracker bug:

https://www.freecadweb.org/tracker/view.php?id=2463

The situation is this: The top line is not detected as intersection because it is tangent.

**Standalone reproduction**

I have recreated the whole using just OCCT.

The test consist in using both algorithms on the circumference and top line. I first ensure that the endpoint is within the precision asked to the algorithms.

A first pass is with the EXACT geometry above, so tangent line.

A second pass is with the starting point of the line (the one farthest from the circumference) at another position, so that it is NOT tangent.

**When the line is tangent the intersection is not detected, when the line is NOT tangent, the intersection is detected.**

**Question:**Am I asking the algorithm something I should not, or is it a bug?

Code: Select all

```
# include <Geom_Circle.hxx>
# include <Geom_Curve.hxx>
# include <Geom_Line.hxx>
# include <Geom_Plane.hxx>
# include <GC_MakeCircle.hxx>
# include <GC_MakeSegment.hxx>
# include <gp.hxx>
# include <gp_Ax2.hxx>
# include <gp_Pnt.hxx>
# include <gp_Dir.hxx>
# include <gp_Pln.hxx>
# include <GeomAPI.hxx>
# include <Geom2d_Curve.hxx>
# include <Geom2dAPI_InterCurveCurve.hxx>
# include <GeomAPI_ExtremaCurveCurve.hxx>
int main()
{
double precision = 1.0e-8;
// A line segment
gp_Pnt p1(-80.461134694338, 53.07587187722, 0.0), p2(-31.501464018476, 67.029737602069, 0.0);
GC_MakeSegment ms(p1, p2);
Handle(Geom_TrimmedCurve) tc_line = ms.Value();
// A circunference
gp_Pnt center(-18.339655323916, 20.849340929486, 0.0);
double radius = 48.019394466707;
gp_Dir norm(0,0,1);
gp_Ax2 xdir(center, norm);
GC_MakeCircle mc(xdir, radius);
Handle(Geom_Circle) circle = mc.Value();
// NOTE: The line is made to be substantially tangent to the circunference
double distance_endpoint_linesegment_to_center_cirncunf = center.Distance(p2);
printf("SETUP 1:\n");
printf("========\n");
printf("Description: Circle with touching tangential line\n\n");
printf("Distance from endpoint of line segment to center circunf: %f\n", distance_endpoint_linesegment_to_center_cirncunf);
printf("Distance from circunference to endpoint of line segment: %.10e\n\n", distance_endpoint_linesegment_to_center_cirncunf - radius);
// Algorithm1: 2D intersection with Geom2dAPI_InterCurveCurve
gp_Pln plane(gp_Pnt(0,0,0),gp_Dir(0,0,1));
Handle(Geom2d_Curve) circle2dCurve;
circle2dCurve = GeomAPI::To2d(circle, plane);
Handle(Geom2d_Curve) line2dCurve;
line2dCurve = GeomAPI::To2d(tc_line, plane);
Geom2dAPI_InterCurveCurve Intersector2d;
printf("Algorithm: Geom2dAPI_InterCurveCurve - precision/tolerance: %.10g\n",precision);
Intersector2d.Init(circle2dCurve, line2dCurve, 1.0e-8);
printf("\tGeom2dAPI_InterCurveCurve - NbPoints: %d\n", Intersector2d.NbPoints());
printf("\tGeom2dAPI_InterCurveCurve - NbSegments: %d\n", Intersector2d.NbSegments());
for (int i=1; i <= Intersector2d.NbPoints(); i++) {
gp_Pnt2d p = Intersector2d.Point(i);
printf("\t%d: (%f,%f,0)\n",i,p.X(),p.Y());
}
// Algorithm2: GeomAPI_ExtremaCurveCurve
printf("\nAlgorithm: GeomAPI_ExtremaCurveCurve - precision/tolerance: %.10g\n",precision);
GeomAPI_ExtremaCurveCurve Intersector3d(circle, tc_line);
printf("\tGeomAPI_ExtremaCurveCurve - NbExtrema: %d\n", Intersector3d.NbExtrema());
// Setup 2: non tangencial line, same endpoint
gp_Pnt p3(-100.0,30.0,0.0);
GC_MakeSegment ms2(p3, p2);
Handle(Geom_TrimmedCurve) tc_line2 = ms2.Value();
double distance_endpoint_linesegment_to_center_cirncunf2 = center.Distance(p2);
printf("\nSETUP 2:\n");
printf("========\n");
printf("Description: Circle with touching NON-tangential line\n\n");
printf("Distance from endpoint of line segment to center circunf: %f\n", distance_endpoint_linesegment_to_center_cirncunf2);
printf("Distance from circunference to endpoint of line segment: %.10e\n\n", distance_endpoint_linesegment_to_center_cirncunf2 - radius);
// Algorithm1: 2D intersection with Geom2dAPI_InterCurveCurve
Handle(Geom2d_Curve) line2dCurve2;
line2dCurve2 = GeomAPI::To2d(tc_line2, plane);
printf("Algorithm: Geom2dAPI_InterCurveCurve - precision/tolerance: %.10g\n",precision);
Intersector2d.Init(circle2dCurve, line2dCurve2, 1.0e-8);
printf("\tGeom2dAPI_InterCurveCurve - NbPoints: %d\n", Intersector2d.NbPoints());
printf("\tGeom2dAPI_InterCurveCurve - NbSegments: %d\n", Intersector2d.NbSegments());
for (int i=1; i <= Intersector2d.NbPoints(); i++) {
gp_Pnt2d p = Intersector2d.Point(i);
printf("\t%d: (%f,%f,0)\n",i,p.X(),p.Y());
}
// Algorithm2: GeomAPI_ExtremaCurveCurve
printf("\nAlgorithm: GeomAPI_ExtremaCurveCurve - precision/tolerance: %.10g\n",precision);
GeomAPI_ExtremaCurveCurve Intersector3d2(circle, tc_line2);
printf("\tGeomAPI_ExtremaCurveCurve - NbExtrema: %d\n", Intersector3d2.NbExtrema());
return 0;
}
```

Code: Select all

```
g++ intersector.cpp -I/usr/include/occt -L/usr/lib/x86_64-linux-gnu -lTKG3d -lTKernel -lTKMath -lTKGeomBase -lTKGeomAlgo -o intersector
```

Code: Select all

```
./intersector
```

Word size of OS: 64-bit

Word size of FreeCAD: 64-bit

Version: 0.18.14874 (Git)

Build type: Debug

Branch: _2463_

Hash: 1d3f3ab7ec0b483c4459646e0b1e63c7314c51a5

Python version: 2.7.15rc1

Qt version: 4.8.7

Coin version: 4.0.0a

OCC version: 7.3.0