# # alien.cad # # 2D example # # Neil Gershenfeld # CBA MIT 7/29/07 # # (c) Massachusetts Institute of Technology 2007 # Permission granted for experimental and personal use; # license for commercial sale available from MIT. # # # define shapes and transformation # # circle(x0, y0, r) # cylinder(x0, y0, z0, z1, r) # cone(x0, y0, z0, h, r0) # sphere(x0, y0, z0, r) # torus(x0, y0, z0, r0, r1) # rectangle(x0, x1, y0, y1) # cube(x0, x1, y0, y1, z0, z1) # pyramid(x0, y0, z0, h, r) # add(part1, part2) # subtract(part1, part2) # intersect(part1, part2) # move(part,dx,dy) # translate(part,dx,dy,dz) # rotate(part, angle) # rotate_90(part) # rotate_180(part) # rotate_270(part) # rotate_x(part, angle) # rotate_y(part, angle) # rotate_z(part, angle) # reflect_x(part) # reflect_y(part) # reflect_z(part) # reflect_xy(part) # reflect_xz(part) # reflect_yz(part) # scale_x(part, x0, sx) # scale_y(part, y0, sy) # scale_z(part, z0, sz) # taper_x_y(part, x0, y0, y1, s0, s1) # taper_x_z(part, x0, z0, z1, s0, s1) # taper_y_z(part, x0, z0, z1, s0, s1) # taper_xy_z(part, x0, y0, z0, z1, s0, s1) # (many more to come) # poly_x(part, x0, z0, z1, a, b, ...) # poly_y(part, y0, z0, z1, a, b, ...) # poly_xy(part, x0, y0, z0, z1, a, b, ...) def circle(x0, y0, r): part = "(((X-x0)**2 + (Y-y0)**2) <= r**2)" part = replace(part,'x0',str(x0)) part = replace(part,'y0',str(y0)) part = replace(part,'r',str(r)) return part def cylinder(x0, y0, z0, z1, r): part = "(((X-x0)**2 + (Y-y0)**2 <= r**2) & (Z >= z0) & (Z <= z1))" part = replace(part,'x0',str(x0)) part = replace(part,'y0',str(y0)) part = replace(part,'z0',str(z0)) part = replace(part,'z1',str(z1)) part = replace(part,'r',str(r)) return part def cone(x0, y0, z0, h, r0): part = "((sqrt((X-x0)**2 + (Y-y0)**2) <= (r0 - (Z-z0)*r0/h)) & (Z >= z0) & (Z <= (z0+h)))" part = replace(part,'x0',str(x0)) part = replace(part,'y0',str(y0)) part = replace(part,'z0',str(z0)) part = replace(part,'r0',str(r0)) part = replace(part,'h',str(h)) return part def sphere(x0, y0, z0, r): part = "(((X-x0)**2 + (Y-y0)**2 + (Z-z0)**2) <= r**2)" part = replace(part,'x0',str(x0)) part = replace(part,'y0',str(y0)) part = replace(part,'z0',str(z0)) part = replace(part,'r',str(r)) return part def torus(x0, y0, z0, r0, r1): part = "(((r0 - sqrt((X-x0)**2 + (Y-y0)**2))**2 + (Z-z0)**2) <= r1**2)" part = replace(part,'x0',str(x0)) part = replace(part,'y0',str(y0)) part = replace(part,'z0',str(z0)) part = replace(part,'r0',str(r0)) part = replace(part,'r1',str(r1)) return part def rectangle(x0, x1, y0, y1): part = "((X >= x0) & (X <= x1) & (Y >= y0) & (Y <= y1))" part = replace(part,'x0',str(x0)) part = replace(part,'x1',str(x1)) part = replace(part,'y0',str(y0)) part = replace(part,'y1',str(y1)) return part def right_triangle(x0, y0, l): part = "((X > x0) & (X < x0 + l - (Y-y0)) & (Y > y0))" part = replace(part,'x0',str(x0)) part = replace(part,'y0',str(y0)) part = replace(part,'l',str(l)) return part def cube(x0, x1, y0, y1, z0, z1): part = "((X >= x0) & (X <= x1) & (Y >= y0) & (Y <= y1) & (Z >= z0) & (Z <= z1))" part = replace(part,'x0',str(x0)) part = replace(part,'x1',str(x1)) part = replace(part,'y0',str(y0)) part = replace(part,'y1',str(y1)) part = replace(part,'z0',str(z0)) part = replace(part,'z1',str(z1)) return part def pyramid(x0, y0, z0, h, r): part = "((X >= (x0-r*(1-(Z-z0)/h))) & (X <= (x0+r*(1-(Z-z0)/h))) & (Y >= (y0-r*(1-(Z-z0)/h))) & (Y <= (y0+r*(1-(Z-z0)/h))) & (Z >= z0) & (Z <= (z0+h)))" part = replace(part,'x0',str(x0)) part = replace(part,'y0',str(y0)) part = replace(part,'z0',str(z0)) part = replace(part,'r',str(r)) part = replace(part,'h',str(h)) return part def add(part1, part2): part = "(part1) | (part2)" part = replace(part,'part1',part1) part = replace(part,'part2',part2) return part def subtract(part1, part2): part = "(part1) & ~(part2)" part = replace(part,'part1',part1) part = replace(part,'part2',part2) return part def intersect(part1, part2): part = "(part1) & (part2)" part = replace(part,'part1',part1) part = replace(part,'part2',part2) return part def move(part,dx,dy): part = replace(part,'X','(X-'+str(dx)+')') part = replace(part,'Y','(Y-'+str(dy)+')') return part def translate(part,dx,dy,dz): part = replace(part,'X','(X-'+str(dx)+')') part = replace(part,'Y','(Y-'+str(dy)+')') part = replace(part,'Z','(Z-'+str(dz)+')') return part def rotate(part, angle): angle = angle*pi/180 part = replace(part,'X','(cos(angle)*X+sin(angle)*y)') part = replace(part,'Y','(-sin(angle)*X+cos(angle)*y)') part = replace(part,'y','Y') part = replace(part,'angle',str(angle)) return part def rotate_90(part): part = reflect_xy(part) part = reflect_y(part) return part def rotate_180(part): part = reflect_xy(part) part = reflect_y(part) part = reflect_xy(part) part = reflect_y(part) return part def rotate_270(part): part = reflect_xy(part) part = reflect_y(part) part = reflect_xy(part) part = reflect_y(part) part = reflect_xy(part) part = reflect_y(part) return part def rotate_x(part, angle): angle = angle*pi/180 part = replace(part,'Y','(cos(angle)*Y+sin(angle)*z)') part = replace(part,'Z','(-sin(angle)*Y+cos(angle)*z)') part = replace(part,'z','Z') part = replace(part,'angle',str(angle)) return part def rotate_y(part, angle): angle = angle*pi/180 part = replace(part,'X','(cos(angle)*X+sin(angle)*z)') part = replace(part,'Z','(-sin(angle)*X+cos(angle)*z)') part = replace(part,'z','Z') part = replace(part,'angle',str(angle)) return part def rotate_z(part, angle): angle = angle*pi/180 part = replace(part,'X','(cos(angle)*X+sin(angle)*y)') part = replace(part,'Y','(-sin(angle)*X+cos(angle)*y)') part = replace(part,'y','Y') part = replace(part,'angle',str(angle)) return part def reflect_x(part): part = replace(part,'X','-X') return part def reflect_y(part): part = replace(part,'Y','-Y') return part def reflect_z(part): part = replace(part,'Z','-Z') return part def reflect_xy(part): part = replace(part,'X','temp') part = replace(part,'Y','X') part = replace(part,'temp','Y') return part def reflect_xz(part): part = replace(part,'X','temp') part = replace(part,'Z','X') part = replace(part,'temp','Z') return part def reflect_yz(part): part = replace(part,'Y','temp') part = replace(part,'Z','Y') part = replace(part,'temp','Z') return part def scale_x(part, x0, sx): part = replace(part,'X','(x0 + (X-x0)/sx)') part = replace(part,'x0',str(x0)) part = replace(part,'sx',str(sx)) return part def scale_y(part, y0, sy): part = replace(part,'Y','(y0 + (Y-y0)/sy)') part = replace(part,'y0',str(y0)) part = replace(part,'sy',str(sy)) return part def scale_z(part, z0, sz): part = replace(part,'Z','(z0 + (Z-z0)/sz)') part = replace(part,'z0',str(z0)) part = replace(part,'sz',str(sz)) return part def taper_x_y(part, x0, y0, y1, s0, s1): part = replace(part,'X','(x0 + (X-x0)*(y1-y0)/(s1*(Y-y0) + s0*(y1-Y)))') part = replace(part,'x0',str(x0)) part = replace(part,'y0',str(y0)) part = replace(part,'y1',str(y1)) part = replace(part,'s0',str(s0)) part = replace(part,'s1',str(s1)) return part def taper_x_z(part, x0, z0, z1, s0, s1): part = replace(part,'X','(x0 + (X-x0)*(z1-z0)/(s1*(Z-z0) + s0*(z1-Z)))') part = replace(part,'x0',str(x0)) part = replace(part,'z0',str(z0)) part = replace(part,'z1',str(z1)) part = replace(part,'s0',str(s0)) part = replace(part,'s1',str(s1)) return part def taper_y_z(part, y0, z0, z1, s0, s1): part = replace(part,'Y','(y0 + (Y-y0)*(z1-z0)/(s1*(Z-z0) + s0*(z1-Z)))') part = replace(part,'y0',str(y0)) part = replace(part,'z0',str(z0)) part = replace(part,'z1',str(z1)) part = replace(part,'s0',str(s0)) part = replace(part,'s1',str(s1)) return part def taper_xy_z(part, x0, y0, z0, z1, s0, s1): part = replace(part,'X','(x0 + (X-x0)*(z1-z0)/(s1*(Z-z0) + s0*(z1-Z)))') part = replace(part,'Y','(y0 + (Y-y0)*(z1-z0)/(s1*(Z-z0) + s0*(z1-Z)))') part = replace(part,'x0',str(x0)) part = replace(part,'y0',str(y0)) part = replace(part,'z0',str(z0)) part = replace(part,'z1',str(z1)) part = replace(part,'s0',str(s0)) part = replace(part,'s1',str(s1)) return part # # my functions # def scale(part, s): part = scale_x(part,0,s) part = scale_y(part,0,s) part = scale_z(part,0,s) return part # # define part # # I measured the cardboard thickness at # ~4mm == ~.16in # params cth = .16 # cardboard thickness th = .05 # tooth height tw = .1 # tooth width swr = 1 # slot width to cardboard thickness ratio rw = .5 # ring width rs = .7 # ring squeeze ratio rt = .8 # ring thickness ratio # ring ring = circle(0,0,rw) ring = subtract(ring, rectangle(-1,1,0,1)) ring = subtract(ring, scale(ring, rt)) ring = move(ring, 0, -rw) #ring extender w/ teeth rect = rectangle(-.05,.05,-.25,.25) ring = add(ring, move(rect,-rw+rw*((1-rt)/2), -rw/2)) ring = add(ring, move(rect,rw-rw*((1-rt)/2), -rw/2)) tooth = rectangle(-1*tw, tw, -1*th, th) ring = add (ring, move(tooth,rw+.01,-1*th)) ring = add (ring, move(tooth,rw+.01,-2*cth)) ring = add (ring, move(tooth,-1*(rw+.01),-1*th)) ring = add (ring, move(tooth,-1*(rw+.01),-2*cth)) # ring connector ringConnector = rectangle(-1*rw-.25,rw+.25,-.25,.25) slot = rectangle(-1*tw, tw, -1*cth/2*swr, cth/2*swr) ringConnector = subtract(ringConnector, move(scale_x(slot, 0, 1.2), -1*rw*rs,0)) ringConnector = subtract(ringConnector, move(scale_x(slot, 0, 1.2), rw*rs,0)) slot = rotate(slot, 90) ringConnector = subtract(ringConnector, move(slot, 0, -cth/2-tw)) ringConnector = subtract(ringConnector, move(slot, 0, cth/2+tw)) # position parts ring = move(ring, 1.5, 2) ringConnector = move(ringConnector, 1.5, 2.5) kit = add(ring, ringConnector) # # define limits and parameters # shift = 9 kit=move(kit, shift, 0) xmin = shift dxy = 4 cad.xmin = xmin # min x to render cad.xmax = cad.xmin + dxy # max x to render cad.ymin = 0 # min y to render cad.ymax = cad.ymin + dxy # max y to render dpi = 200 # low resolution for previewing #dpi = 500 # high resolution for machining nxy = int(dpi*(cad.xmax-cad.xmin)) cad.nx = nxy # x points to render cad.ny = nxy # y points to render cad.inches_per_unit = 1 # use inch units cad.view('xy') # show xy view # # assign part to cad.function # cad.function = kit