Rebuild a curve with no inflection points

Is there an easy way to do this? The rebuild command always puts some small inflections when I rebuild two lines connected with a radius fillet. I use manual point manipulation or the fair command to force the curve to only have curvature in one direction. Is there an easier way to do this? Has anyone written a grasshopper script that does this?

Hello - that will be tough if it all needs to be one curve, espcially if there are tangent segments.

-Pascal

The script below traces the control points of the (NURBS curve equivalent) input curve to a new uniform curve. It does this at various NURBS curve degrees and outputs the one that deviates least from the input.

image

import Rhino
import Rhino.Geometry as rg
import rhinoscriptsyntax as rs
import scriptcontext as sc

def main():
    
    gCrvs = rs.GetObjects(
        "Select curves",
        filter=rs.filter.curve,
        preselect=True)
    if gCrvs is None: return
    
    for gCrv in gCrvs:
        crv = rs.coercecurve(gCrv)
        
        nc0 = crv.ToNurbsCurve() # Regardless if crv already is one.
        
        ncs_WIP = []
        devs = []
        
        for iDeg in range(1, 11+1):
            
            if nc0.Points.Count < (iDeg + 1):
                break
            
            nc_WIP = rg.NurbsCurve.Create(
                periodic=nc0.IsPeriodic,
                degree=iDeg,
                points=[cp.Location for cp in nc0.Points])
            
            if nc_WIP is None:
                continue
            
            rc = rg.Curve.GetDistancesBetweenCurves(
                nc_WIP, nc0, tolerance=0.1*sc.doc.ModelAbsoluteTolerance)
            
            if not rc[0]:
                continue
            
            ncs_WIP.append(nc_WIP)
            
            devs.append(rc[1])
        
        if len(ncs_WIP) == 0:
            print "No curves were generated for {}.".format(gCrv)
            continue
        
        nc_LeastDev = ncs_WIP[devs.index(min(devs))]
        
        nc_LeastDev.Domain = nc0.Domain
        
        if (
            isinstance(crv, rg.NurbsCurve) and
            nc_LeastDev.EpsilonEquals(nc0, Rhino.RhinoMath.ZeroTolerance)
        ):
            print "Input and output curves are equivalent for {}.".format(gCrv)
        else:
            gOut = sc.doc.Objects.AddCurve(curve=nc_LeastDev)
            if gOut == gOut.Empty:
                print "Could not add curve to document."
                continue
            
            sc.doc.Objects.Select(objectId=gOut)
    
    sc.doc.Views.Redraw()

if __name__ == '__main__': main()
3 Likes

I wish I understood scripting better. I have no clue what it is doing or how to use it.

Am I understanding it is using the control points of the sub curves to create a new curve and outputs the curve with the degree which results in the least deviation? If that is the case I think I could write a grasshopper script that would do that.

To test the script, run _EditPythonScript, copy and paste the code into the Rhino Python Editor, then press Ctrl-F5 to run.

This page explains how to set up quick access to a script,
Integrating macros and scripts into your workspace [McNeel Wiki]

The script does what you state except the PolyCurve is first converted into a NurbsCurve. Doing so adds a control point to the middle of the line segments (when the PolyCurve contains only LineCurves and ArcCurves), resulting in the curvature tapering at the ends similar to the adjusted curve in your image.

I haven’t found a great solution to this yet. I haven’t played with Steve’s script yet. I have been working the curves by hand with the use of rebuild, fair, smooth, and cage edit with some sucess.