diff --git a/cadquery/hull.py b/cadquery/hull.py index a10131b10..0347acc5a 100644 --- a/cadquery/hull.py +++ b/cadquery/hull.py @@ -198,6 +198,14 @@ def _pt_arc(p: Point, a: Arc) -> Tuple[float, float, float, float]: def pt_arc(p: Point, a: Arc) -> Tuple[float, Segment]: + # Calculate the distance from the point to the arc's center + l = sqrt((p.x - a.c.x) ** 2 + (p.y - a.c.y) ** 2) + + # If the point is inside the circle, no real tangent exists. + # Return an infinite angle to disqualify this path for the hull algorithm. + if l < a.r: + return inf, Segment(Point(inf, inf), Point(inf, inf)) + x, y = p.x, p.y x1, y1, x2, y2 = _pt_arc(p, a) @@ -210,6 +218,13 @@ def pt_arc(p: Point, a: Arc) -> Tuple[float, Segment]: def arc_pt(a: Arc, p: Point) -> Tuple[float, Segment]: + # Calculate the distance from the point to the arc's center + l = sqrt((p.x - a.c.x) ** 2 + (p.y - a.c.y) ** 2) + + # If the point is inside the circle, no real tangent exists. + if l < a.r: + return inf, Segment(Point(inf, inf), Point(inf, inf)) + x, y = p.x, p.y x1, y1, x2, y2 = _pt_arc(p, a) @@ -223,6 +238,11 @@ def arc_pt(a: Arc, p: Point) -> Tuple[float, Segment]: def arc_arc(a1: Arc, a2: Arc) -> Tuple[float, Segment]: + # Add a safety check to see if the arcs are identical. + # This prevents division by zero if they have the same center and radius. + if a1 is a2 or (a1.c == a2.c and a1.r == a2.r): + return inf, Segment(Point(inf, inf), Point(inf, inf)) + r1 = a1.r xc1, yc1 = a1.c.x, a1.c.y diff --git a/doc/primer.rst b/doc/primer.rst index 60549f81c..e107f61c1 100644 --- a/doc/primer.rst +++ b/doc/primer.rst @@ -41,11 +41,11 @@ CadQuery is composed of 4 different API, which are implemented on top of each ot #. :class:`~cadquery.Assembly` 2. The Direct API #. :class:`~cadquery.Shape` -2. The Geometry API +3. The Geometry API #. :class:`~cadquery.Vector` #. :class:`~cadquery.Plane` #. :class:`~cadquery.Location` -3. The OCCT API +4. The OCCT API The Fluent API ~~~~~~~~~~~~~~~~~~~~~~