Rhino & GrasshopperPythonRhino 6–8 · built-in Python (rhinoscriptsyntax)MIT license
Find the tightest radius on any curve in Rhino (Python)
Before you program a cutter along a curve — a cam profile, a grinding-wheel path, an imported spline from a customer file — one number decides which tools are even possible: the tightest radius on that curve. A tool with a bigger radius gouges; a corner radius you didn't notice becomes a dwell mark. This script samples the curve densely, finds the minimum radius of curvature, drops a point and a labeled text dot on the exact spot, and prints the largest tool diameter that can follow the curve without gouging.
Before you run it
- Rhino 6, 7, or 8 (script uses only
rhinoscriptsyntax) - Run via
EditPythonScript(Rhino 6/7) or theScriptEditor(Rhino 8)
The code
"""Find the tightest radius on a curve - before your toolpath does.
Rhino 6/7: Tools > PythonScript > Edit, paste, run.
Rhino 8: ScriptEditor (Python 2/3 both fine - this is plain rhinoscriptsyntax).
"""
import rhinoscriptsyntax as rs
SAMPLES = 500 # more = finer scan; 500 is plenty for most curves
def main():
curve = rs.GetObject("Select a curve to analyze", rs.filter.curve)
if not curve:
return
t0, t1 = rs.CurveDomain(curve)
min_radius = None
min_param = None
for i in range(SAMPLES + 1):
t = t0 + (t1 - t0) * i / SAMPLES
cc = rs.CurveCurvature(curve, t)
if cc is None: # straight section: no curvature here
continue
radius = cc[3]
if min_radius is None or radius < min_radius:
min_radius = radius
min_param = t
if min_radius is None:
print("Curve is straight everywhere - no finite radius.")
return
pt = rs.EvaluateCurve(curve, min_param)
rs.AddPoint(pt)
rs.AddTextDot("R min = {:.3f}".format(min_radius), pt)
print("Tightest radius: {:.3f} at parameter {:.4f}".format(min_radius, min_param))
print("Largest non-gouging tool: {:.3f} dia (concave side).".format(2 * min_radius))
main()How it works
rs.CurveDomaingives the parameter range; the loop walks it inSAMPLESeven steps — parameter-space sampling, simple and good enough for a scan.rs.CurveCurvature(curve, t)returns point, tangent, center, radius, and curvature vector at the parameter; index[3]is the radius. On straight sections curvature is zero and the call returnsNone, which the loop just skips.- The winner gets
rs.AddPoint+rs.AddTextDot, so the answer is on the geometry where a programmer will actually see it, not buried in a console. 2 × R minis the largest cutter that can ride the concave side without gouging — the number you take to CAM.
Gotchas & honest limits
- Sampling can miss a spike between samples on pathological curves; for certification-grade analysis use Rhino's
CurvatureGraphalongside. For tool selection, 500 samples is plenty. - The gouge limit applies to concave regions relative to your cut side. A convex-only curve doesn't limit tool size.
- Polylines have zero radius at their kinks — the script will (correctly) report ~0 at a corner. Fillet first, then re-scan.
- Works on planar and 3D curves alike; for 3D remember the radius is measured in the osculating plane, not in your machining plane.
Goes deeper
Want this adapted to your shop — or built into a real tool?
Samples are the free 80%. The last 20% is the part I do for a living.