Skip to content

Instantly share code, notes, and snippets.

@ryansturmer
Created November 3, 2016 03:46
Show Gist options
  • Save ryansturmer/62cc4632c5d6db8162e56acac3925993 to your computer and use it in GitHub Desktop.
Save ryansturmer/62cc4632c5d6db8162e56acac3925993 to your computer and use it in GitHub Desktop.
Functions for generating G-Code for mitered box panels
from math import cos, sin, tan, atan2, atan, pi
def gx(n, x=None,y=None,z=None, f=None):
retval = ['G%d' % n]
for a,b in zip(('X','Y','Z','F'), (x, y, z, f)):
if b is not None:
if a == 'F':
b *= 60.0 # Feedrates in ipm not ips
retval.append(' %s%0.4f' % (a,b))
return ''.join(retval)
def g0(x=None,y=None,z=None):
return gx(0,x,y,z)
def g1(x=None,y=None,z=None, f=None):
return gx(1,x,y,z,f)
def offset(line, amount):
a = line[0]
b = line[1]
theta = atan2(b[1]-a[1],b[0]-a[0])+pi/2
ap = (a[0]+amount*cos(theta), a[1]+amount*sin(theta))
bp = (b[0]+amount*cos(theta), b[1]+amount*sin(theta))
return ap,bp
def create_miter(a,b,angle=45,step=0.005,thickness=0.5,pullup=0.25,feedrate=4.0):
g = [g0(*a),g1(z=0,f=feedrate)]
z = 0
l = 0
#print "creating miter for " + str(a) + " -> " + str(b)
line = (a,b)
direction = True
while z > -thickness:
a,b = line
if(direction):
g.append(g1(*b))
else:
g.append(g1(*a))
line = offset(line, step)
a,b = line
z -= step*tan(angle*pi/180)
# Step over
if(direction):
g.append(g1(*b,z=z))
else:
g.append(g1(*a,z=z))
direction = not direction
g.append(g0(z=pullup))
return g
def create_cutout(sides, thickness=0.5, pullup=0.25, feedrate=1.5, pass_depth=0.125):
start = sides[0][0]
g = [g0(*start),g1(z=0,f=feedrate)]
z = 0;
while True:
z -= pass_depth
if z < -thickness:
z = -thickness
g.append(g1(z=z,f=feedrate))
for a,b in sides:
g.append(g1(*b,f=feedrate))
if z <= -thickness:
break
g.append(g0(z=pullup))
return g
class Panel(object):
def __init__(self, w, h, thickness):
self.w = w
self.h = h
self.miters = {}
self.cutter = 0.125
self.cut_speed = 2.0
self.miter_speed = 4.0
self.safe_pullup = 0.25
self.thickness = thickness
self.miter_step = 0.005
self.x = 0
self.y = 0
def miter(self, side, angle):
self.miters[side] = angle
def translate(self, dx=0, dy=0):
self.x+=dx
self.y+=dy
def render(self):
cr = self.cutter/2.0
corners = [
[self.x-cr, self.y+self.h+cr],
[self.x+self.w+cr, self.y+self.h+cr],
[self.x+self.w+cr, self.y-cr],
[self.x-cr, self.y-cr]
]
side_names = ['w','n','e','s']
sides = [(corners[i-1],corners[i]) for i in range(4)]
sides_dict = dict(zip(side_names, sides))
miters = []
# Create miters
for name, angle in self.miters.items():
line = sides_dict[name]
miter = create_miter(line[0],line[1],
angle=angle,
step=self.miter_step,
thickness=self.thickness,
pullup=self.safe_pullup,
feedrate=self.miter_speed
)
miters.append(miter)
if 'n' in self.miters:
miter_length = self.thickness*1.0/tan(self.miters['n']*pi/180.0)
corners[0][1] += miter_length
corners[1][1] += miter_length
if 'e' in self.miters:
miter_length = self.thickness*1.0/tan(self.miters['e']*pi/180.0)
corners[1][0] += miter_length
corners[2][0] += miter_length
if 's' in self.miters:
miter_length = self.thickness*1.0/tan(self.miters['s']*pi/180.0)
corners[2][1] -= miter_length
corners[3][1] -= miter_length
if 'w' in self.miters:
miter_length = self.thickness*1.0/tan(self.miters['w']*pi/180.0)
corners[3][0] -= miter_length
corners[0][0] -= miter_length
sides = [(corners[i-1],corners[i]) for i in range(4)]
sides_dict = dict(zip(side_names, sides))
cutout = create_cutout(sides,thickness=self.thickness)
retval = []
for miter in miters:
retval.extend(miter)
retval.extend(cutout)
return retval
if __name__ == "__main__":
# Bottom Panel(1,5.5,0.5)
bottom = Panel(1,5.5, 0.5)
bottom.miter_step = 0.010
bottom.miter_speed = 5.0
bottom.miter('w', 45)
bottom.miter('e', 45)
g = [
'G20',
g0(z=0.5),
'M4',
'G4 P3'
]
g.extend(bottom.render())
with open('bottom.g', 'w') as fp:
fp.write('\n'.join(g))
side = Panel(3.5,5.5, 0.5)
side.miter_step = 0.010
side.miter_speed = 5.0
side.miter('w', 45)
g = [
'G20',
g0(z=0.5),
'M4',
'G4 P3'
]
g.extend(side.render())
with open('side.g', 'w') as fp:
fp.write('\n'.join(g))
roof = Panel(6.25,8, 0.5)
roof.miter_step = 0.010
roof.miter_speed = 5.0
roof.miter('e', 45)
g = [
'G20',
g0(z=0.5),
'M4',
'G4 P3'
]
g.extend(roof.render())
with open('roof.g', 'w') as fp:
fp.write('\n'.join(g))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment