Skip to main content

raygeo.geo.algo.fillet

Pure-geometry fillet operations.

Domain-neutral utilities for creating circular fillet arcs, appending them to polylines, and trimming to safe spans.

  • create_fillet_polyline — circular arc tangent to a direction.
  • append_end_fillets — fillet both ends of an open polyline.
  • trim_to_safe_fillet_span — longest sub-span whose end fillets avoid obstacles.
  • get_descending_radius_fillet — try fillets at descending radii until one fits.

Functions

append_end_fillets()

append_end_fillets(
polyline: Sequence[tuple[float, float]],
radius: float,
sweep_angle: float,
start_side: float,
end_side: float,
) -> list[tuple[float, float]]

Append fillet arcs to both ends of an open polyline.

A reversed fillet is added at the start (using start_side) and a forward fillet at the end (using end_side), producing a smooth rounded path.

ParameterTypeDescription
polylineSequence[tuple[float, float]]Input open polyline.
radiusfloatFillet radius.
sweep_anglefloatArc sweep angle in radians.
start_sidefloatOffset side for the start fillet (+1 left, -1 right).
end_sidefloatOffset side for the end fillet (+1 left, -1 right).
Returnslist[tuple[float, float]]Full polyline with fillets.

 rounds both ends of an open polyline with reversed/forward fillet arcs

append_end_fillets rounds both ends of an open polyline with reversed/forward fillet arcs

create_fillet_polyline()

create_fillet_polyline(
p: tuple[float, float],
dir: tuple[float, float],
radius: float,
sweep_angle: float,
side: float,
reverse: bool,
) -> tuple[tuple[float, float], list[tuple[float, float]]]

Create a circular fillet arc tangent to dir at p.

side selects the offset side (+1 = left of dir, -1 = right). When reverse is True the arc curls back opposite to dir.

ParameterTypeDescription
ptuple[float, float]Start point (x, y).
dirtuple[float, float]Tangent direction vector (dx, dy).
radiusfloatFillet radius.
sweep_anglefloatArc sweep angle in radians.
sidefloatOffset side (+1 left, -1 right).
reverseboolWhether the arc is reversed.
Returnstuple[tuple[float, float], list[tuple[float, float]]](center, polyline) — arc centre and fillet vertices.

 generates circular fillet arcs at any sweep angle, tangent to a direction

create_fillet_polyline generates circular fillet arcs at any sweep angle, tangent to a direction

 with  (left) and  (right) of the direction vector

create_fillet_polyline with side=+1 (left) and side=-1 (right) of the direction vector

fillet_arc_ends()

fillet_arc_ends(
arc: Sequence[tuple[float, float]],
pocket_boundary: Sequence[tuple[float, float]],
islands: Sequence[Sequence[tuple[float, float]]] = [],
tool_radius: float = 3,
wall_margin: float = 0,
) -> list[tuple[float, float]]

Round both ends of a cutting arc with quarter-circle fillets.

The arc is trimmed to the longest sub-arc whose tool sweep (arc + end fillets of tool_radius) does not collide with pocket_boundary or islands. A 90° fillet of tool_radius is then appended at each end.

ParameterTypeDescription
arcSequence[tuple[float, float]]Cutting arc vertices (open polyline).
pocket_boundarySequence[tuple[float, float]]Outer boundary of the pocket.
islandsSequence[Sequence[tuple[float, float]]] = []List of island (hole) polygons (default []).
tool_radiusfloat = 3Tool / fillet radius in mm (default 3.0).
wall_marginfloat = 0Extra clearance past tangency (default 0.0).
Returnslist[tuple[float, float]]Filleted arc as an open polyline.

 trims the arc to the longest safe sub-arc and appends quarter-circle fillets

fillet_arc_ends trims the arc to the longest safe sub-arc and appends quarter-circle fillets

find_safe_sweep_end()

find_safe_sweep_end(
arc: Sequence[tuple[float, float]],
pocket_boundary: Sequence[tuple[float, float]],
islands: Sequence[Sequence[tuple[float, float]]] = [],
tool_radius: float = 3,
wall_margin: float = 0,
) -> tuple[tuple[float, float], tuple[float, float]] | None

Find the longest safe sub-arc by iterative sweep shortening.

Returns the two points (enter, exit) delimiting the longest sub-arc of arc whose tool sweep (arc + end fillets of tool_radius) does not collide with pocket_boundary or islands. Shortens from each end until the sweep is clear. Returns None when no usable safe sub-arc remains.

ParameterTypeDescription
arcSequence[tuple[float, float]]Cutting arc vertices (open polyline).
pocket_boundarySequence[tuple[float, float]]Outer boundary of the pocket.
islandsSequence[Sequence[tuple[float, float]]] = []List of island (hole) polygons (default []).
tool_radiusfloat = 3Tool radius in mm (default 3.0).
wall_marginfloat = 0Extra clearance past tangency (default 0.0).
Returnstuple[tuple[float, float], tuple[float, float]] | None(enter, exit) or None.

 returns the (enter, exit) points delimiting the longest safe sub-arc

find_safe_sweep_end returns the (enter, exit) points delimiting the longest safe sub-arc

get_descending_radius_fillet()

get_descending_radius_fillet(
arc: Sequence[tuple[float, float]],
outer_boundary: Sequence[tuple[float, float]],
inner_obstacles: Sequence[Sequence[tuple[float, float]]] = [],
radius: float = 3,
margin: float = 0,
) -> list[tuple[float, float]]

Try fillets at descending radii until one fits.

Starts at radius and halves until either both (or one) end fillet fits, or the radius drops below 0.1; returns the filleted arc, or an empty list if none fits.

The safety distance (radius + margin) stays fixed as the fillet radius shrinks, so the tool clearance remains constant.

ParameterTypeDescription
arcSequence[tuple[float, float]]Cutting arc vertices (open polyline).
outer_boundarySequence[tuple[float, float]]Outer boundary polygon.
inner_obstaclesSequence[Sequence[tuple[float, float]]] = []List of obstacle polygons (default []).
radiusfloat = 3Initial fillet radius in mm (default 3.0).
marginfloat = 0Extra clearance past tangency (default 0.0).
Returnslist[tuple[float, float]]Filleted arc or empty list.

 halves radius until both ends fit, keeping safety distance fixed

get_descending_radius_fillet halves radius until both ends fit, keeping safety distance fixed

trim_to_safe_fillet_span()

trim_to_safe_fillet_span(
polyline: Sequence[tuple[float, float]],
outer_boundary: Sequence[tuple[float, float]],
inner_obstacles: Sequence[Sequence[tuple[float, float]]] = [],
radius: float = 3,
margin: float = 0,
) -> tuple[tuple[float, float], tuple[float, float]] | None

Find the longest sub-span whose end fillets avoid obstacles.

Shortens from each end until the sweep is clear. Returns (enter, exit) or None.

ParameterTypeDescription
polylineSequence[tuple[float, float]]Open polyline to trim.
outer_boundarySequence[tuple[float, float]]Outer boundary polygon.
inner_obstaclesSequence[Sequence[tuple[float, float]]] = []List of obstacle polygons (default []).
radiusfloat = 3Fillet radius (default 3.0).
marginfloat = 0Extra clearance past tangency (default 0.0).
Returnstuple[tuple[float, float], tuple[float, float]] | None(enter, exit) or None.

 finds the longest safe sub-span whose end fillets avoid obstacles (red)

trim_to_safe_fillet_span finds the longest safe sub-span whose end fillets avoid obstacles (red)

try_fillet_one_end()

try_fillet_one_end(
arc: Sequence[tuple[float, float]],
outer_boundary: Sequence[tuple[float, float]],
inner_obstacles: Sequence[Sequence[tuple[float, float]]] = [],
radius: float = 3,
margin: float = 0,
) -> list[tuple[float, float]]

Try a fillet at just one end of an arc when both ends don't fit.

Tests the enter (start) fillet first, then the exit (end) fillet, and returns the first that does not collide with the boundary or obstacles. Falls back to the original arc if neither fits.

ParameterTypeDescription
arcSequence[tuple[float, float]]Cutting arc vertices (open polyline).
outer_boundarySequence[tuple[float, float]]Outer boundary polygon.
inner_obstaclesSequence[Sequence[tuple[float, float]]] = []List of obstacle polygons (default []).
radiusfloat = 3Fillet radius (default 3.0).
marginfloat = 0Extra clearance past tangency (default 0.0).
Returnslist[tuple[float, float]]Arc with optional single-end fillet, or original arc.

 tests the start fillet first; on collision falls back to the end fillet

try_fillet_one_end tests the start fillet first; on collision falls back to the end fillet