Hi,

I’d like to generate a drag knife toolpath using python/grasshopper.

It basically comes down to this:

For each point on a line (with the distance of the points approaching 0), IF continuous, offset this point in the direction of the tangent by the distance the drag knife is from the centre. With all these points combined, you should get a new curve.

However, if it isn’t continuous, it should make a circle segment, with the radius being the distance the drag knife is from the centre.

Here is an illustration of what i mean:

Further down the road i’d also like to export this to gcode.

This is what i’ve written so far (or well, found it in a video) :

import rhinoscriptsyntax as rs

class TanLines:

def **init** (self, INcurve, INnumOfDivs):

self.curve = INcurve

self.numOfDivs = INnumOfDivs

```
def tanPoints(self):
doms = rs.CurveDomain(self.curve)
minDom = doms[0]
maxDom = doms[1]
for i in range(0, 30):
param = (maxDom-minDom)/30 * i
pt = rs.EvaluateCurve(self.curve, param)
tan = rs.CurveTangent(self.curve, param)
tanPt = rs.VectorAdd(tan, pt)
rs.AddLine(pt, tanPt)
curve = rs.GetObject("Select a curve")
obj = TanLines(curve, rs.GetReal("number", 30, 0, 100))
obj.tanPoints();
```

Kind regards,

Thomas

Update: almost there.

This is the current script:

import rhinoscriptsyntax as rs

import Rhino

import scriptcontext

import System.Guid

class TanLines:

def **init** (self, INcurve, INnumOfDivs):

self.curve = INcurve

self.numOfDivs = int(INnumOfDivs)

```
def tanPoints(self):
doms = rs.CurveDomain(self.curve)
minDom = doms[0]
maxDom = doms[1]
points = Rhino.Collections.Point3dList(30)
```

```
for i in range(0, self.numOfDivs):
param = (maxDom-minDom)/self.numOfDivs * i
```

```
pt = rs.EvaluateCurve(self.curve, param)
tan = rs.CurveTangent(self.curve, param)
tanPt = rs.PointAdd(tan, pt)
rs.AddLine(pt, tanPt,)
points.Add(tanPt)
print "Before sort ..."
for point in points:
print "point: {0}".format(point)
nc = Rhino.Geometry.NurbsCurve.Create(False, 2, points)
rc = Rhino.Commands.Result.Failure
if nc and nc.IsValid:
if scriptcontext.doc.Objects.AddCurve(nc)!=System.Guid.Empty:
scriptcontext.doc.Views.Redraw()
rc = Rhino.Commands.Result.Success
return rc
```

curve = rs.GetObject(“Select a curve”)

obj = TanLines(curve, rs.GetReal(“divisions”, 200, 0, 10000))

obj.tanPoints()

This it what it generates:

dragknife.3dm (572.1 KB)

Any help as to how to get the distance of the translated points close to 0, and how to get a circle on places the curve is not continuous?

Regards,

Thomas

I’ve managed to generate the circles on places the curve is not contiuous, but it’s kind of hacky…

Hear me out: First you create a polygon, then you use the FilletCorner command with 0.05 radius,

then you divide the curve in 0,001 parts and run my script and it kinda creates that effect.

It’s hacky but whatever does the trick right?

If someone has tips/other solutions i’d greatly appreciate it!

New code can be found here: (doesn’t include the filletCorners command yet)

```
import rhinoscriptsyntax as rs
import Rhino
import scriptcontext
import System.Guid
class TanLines:
def __init__ (self, INcurve, INdivideBy, INradius):
self.curve = INcurve
self.divideBy = float(INdivideBy)
self.radius = int(INradius)
def tanPoints(self):
doms = rs.CurveDomain(self.curve)
minDom = doms[0]
maxDom = doms[1]
points = Rhino.Collections.Point3dList(30)
lengthCurve = rs.CurveLength(self.curve)
self.numOfDivs = lengthCurve/self.divideBy
for i in range(0, int(self.numOfDivs)):
param = (maxDom-minDom)/self.numOfDivs * i
pt = rs.EvaluateCurve(self.curve, param)
tan = rs.CurveTangent(self.curve, param)
if i < 1:
tan = rs.VectorScale(rs.CurveTangent(self.curve, param), -self.radius*2)
elif i == self.numOfDivs-1:
tan = rs.VectorScale(rs.CurveTangent(self.curve, param), self.radius*2)
else:
tan = rs.VectorScale(rs.CurveTangent(self.curve, param), self.radius)
tanPt = rs.PointAdd(tan, pt)
#rs.AddLine(pt, tanPt)
points.Add(tanPt)
print "Before sort ..."
for point in points:
print "point: {0}".format(point)
nc = Rhino.Geometry.NurbsCurve.Create(False, 1, points)
rc = Rhino.Commands.Result.Failure
if nc and nc.IsValid:
if scriptcontext.doc.Objects.AddCurve(nc)!=System.Guid.Empty:
scriptcontext.doc.Views.Redraw()
rc = Rhino.Commands.Result.Success
return rc
curve = rs.GetObject("Select a curve")
obj = TanLines(curve, rs.GetReal("length", 200, 0, 10000), rs.GetReal("Radius", 200, 0, 10000))
obj.tanPoints()
```

Kind regards,

and please let this be a dialogue

I’m very interested in your script and would like to try it. My question is: how do I load this script into Rhino?

Thanks,

-Justin

@jkindelspire,

copy the script code in your clipboard, then in Rhino type `_EditPythonScript`

and paste it. Now just click on the green triangle to start the script.

c.