def revolve_x(a): ''' Revolve a part in the XY plane about the X axis. ''' # Y' = +/- sqrt(Y**2 + Z**2) pos = a.map(Transform('', 'r+qYqZ', '', '', '', '')) neg = a.map(Transform('', 'nr+qYqZ', '', '', '', '')) m = max(abs(a.bounds.ymin), abs(a.bounds.ymax)) return Shape((pos | neg).math, a.bounds.xmin, -m, -m, a.bounds.xmax, m, m)
def scale_y(part, y0, sy): # Y' = y0 + (Y-y0)/sy return part.map( Transform( 'X', '+f%(y0)g/-Yf%(y0)gf%(sy)g' % locals() if y0 else '/Yf%g' % sy, 'X', '+f%(y0)g*f%(sy)g-Yf%(y0)g' % locals() if y0 else '*Yf%g' % sy))
def scale_x(part, x0, sx): # X' = x0 + (X-x0)/sx return part.map( Transform( '+f%(x0)g/-Xf%(x0)gf%(sx)g' % locals() if x0 else '/Xf%g' % sx, 'Y', '+f%(x0)g*f%(sx)g-Xf%(x0)g' % locals() if x0 else '*Xf%g' % sx, 'Y'))
def scale_z(part, z0, sz): # Z' = z0 + (Y-y0)/sz # Z = (Z'-z0)*sz + z0 return part.map( Transform( 'X', 'Y', '+f%(z0)g/-Zf%(z0)gf%(sz)g' % locals() if z0 else '/Zf%g' % sz, 'X', 'Y', '+f%(z0)g*f%(sz)g-Zf%(z0)g' % locals() if z0 else '*Zf%g' % sz))
def shear_x_y(part, y0, y1, dx0, dx1): dx = dx1 - dx0 dy = y1 - y0 # X' = X-dx0-dx*(Y-y0)/dy # X = X'+dx0+(dx)*(Y-y0)/dy return part.map( Transform('--Xf%(dx0)g/*f%(dx)g-Yf%(y0)gf%(dy)g' % locals(), 'Y', '++Xf%(dx0)g/*f%(dx)g-Yf%(y0)gf%(dy)g' % locals(), 'Y'))
def shear_x_y(part, ymin, ymax, dx0, dx1): dx = dx1 - dx0 dy = ymax - ymin # X' = X-dx0-dx*(Y-ymin)/dy # X = X'+dx0+(dx)*(Y-ymin)/dy return part.map( Transform('--Xf%(dx0)g/*f%(dx)g-Yf%(ymin)gf%(dy)g' % locals(), 'Y', '++Xf%(dx0)g/*f%(dx)g-Yf%(ymin)gf%(dy)g' % locals(), 'Y'))
def reflect_yz(part, y0=0, z0=0): # Y' = y0 + (Z-z0) # Z' = z0 + (Y-y0) # Y = y0 + (Z'-z0) # Z = z0 + (Y'-y0) return part.map( Transform('X', '+f%(y0)g-Zf%(z0)g' % locals(), '+f%(z0)g-Yf%(y0)g' % locals(), 'X', '+f%(y0)g-Zf%(z0)g' % locals(), '+f%(z0)g-Yf%(y0)g' % locals()))
def reflect_xy(part, x0=0, y0=0): # X' = x0 + (Y-y0) # Y' = y0 + (X-x0) # X = x0 + (Y'-y0) # Y = y0 + (X'-x0) return part.map( Transform('+f%(x0)g-Yf%(y0)g' % locals(), '+f%(y0)g-Xf%(x0)g' % locals(), '+f%(x0)g-Yf%(y0)g' % locals(), '+f%(y0)g-Xf%(x0)g' % locals()))
def reflect_xz(part, x0=0, z0=0): # X' = x0 + (Z-z0) # Z' = z0 + (X-x0) # X = x0 + (Z'-z0) # Z = z0 + (X'-x0) return part.map( Transform('+f%(x0)g-Zf%(z0)g' % locals(), 'Y', '+f%(z0)g-Xf%(x0)g' % locals(), '+f%(x0)g-Zf%(z0)g' % locals(), 'Y', '+f%(z0)g-Xf%(x0)g' % locals()))
def scale_xy(part, x0, y0, sxy): # X' = x0 + (X-x0)/sx # Y' = y0 + (Y-y0)/sy # X = (X'-x0)*sx + x0 # Y = (Y'-y0)*sy + y0 return part.map( Transform( '+f%(x0)g/-Xf%(x0)gf%(sxy)g' % locals() if x0 else '/Xf%g' % sxy, '+f%(y0)g/-Yf%(y0)gf%(sxy)g' % locals() if y0 else '/Yf%g' % sxy, '+f%(x0))g*f%(sxy)g-Xf%(x0)g' % locals() if x0 else '*Xf%g' % sxy, '+f%(y0)g*f%(sxy)g-Yf%(y0)g' % locals() if y0 else '*Yf%g' % sxy))
def scale_z_r(part, x0, y0, z0, r0, s0, r1, s1): dr = r1 - r0 # Z' = z0 + (Z-z0)*dr/((s1-s0)*sqrt((X-x0)^2+(Y-y0)^2)-s1*r0+s0*r1) # Z = z0 + (Z'-z0)*((s1-s0)*sqrt((X-x0)^2+(Y-y0)^2)-s1*r0+s0*r1)/dr return part.map( Transform( 'X', 'Y', '+f%(z0)g/*-Zf%(z0)gf%(dr)g+-*-f%(s1)gf%(s0)gr+q-Xf%(x0)gq-Yf%(y0)g*f%(s1)gf%(r0)g*f%(s0)gf%(r1)g' % locals(), 'X', 'Y', '+f%(z0)g/*-Zf%(z0)g+-*-f%(s1)gf%(s0)gr+q-Xf%(x0)gq-Yf%(y0)g*f%(s1)gf%(r0)g*f%(s0)gf%(r1)gf%(dr)g' % locals()))
def rotate(part, angle, x0=0, y0=0): p = move(part, -x0, -y0, 0) angle *= math.pi / 180 ca, sa = math.cos(angle), math.sin(angle) nca, nsa = math.cos(-angle), math.sin(-angle) return move( p.map( Transform('+*f%(ca)gX*f%(sa)gY' % locals(), '+*f%(nsa)gX*f%(ca)gY' % locals(), '+*f%(nca)gX*f%(nsa)gY' % locals(), '+*f%(sa)gX*f%(nca)gY' % locals())), x0, y0, 0)
def scale_cos_x_y(part, x0, y0, y1, amp, off, t0, t1): dy = y1 - y0 t0 = math.radians(t0) t1 = math.radians(t1) # X' = x0 + (X-x0)/(off+amp*math.cos(theta0+(theta1-theta0)*(Y-y0)/dy)) # X = x0 + (X'-x0)*(off+amp*math.cos(theta0+(theta1-theta0)*(Y-y0)/dy)) return part.map( Transform( '/+f%(x0)g-Xf%(x0)g+f%(off)g*f%(amp)gc+f%(t0)g/*-f%(t1)gf%(t0)g-Yf%(y0)gf%(dy)g' % locals(), 'Y', '*+f%(x0)g-Xf%(x0)g+f%(off)g*f%(amp)gc+f%(t0)g/*-f%(t1)gf%(t0)g-Yf%(y0)gf%(dy)g' % locals(), 'Y'))
def scale_xy(part, x0, y0, sx, sy=None): # X' = x0 + (X-x0)/sx # Y' = y0 + (Y-y0)/sy # X = (X'-x0)*sx + x0 # Y = (Y'-y0)*sy + y0 if sy is None: sy = sx return part.map( Transform('+f%(x0)g/-Xf%(x0)gf%(sx)g' % locals(), '+f%(y0)g/-Yf%(y0)gf%(sy)g' % locals(), '+f%(x0)g*f%(sx)g-Xf%(x0)g' % locals(), '+f%(y0)g*f%(sy)g-Yf%(y0)g' % locals()))
def rotate_x(part, angle, y0=0, z0=0): p = move(part, 0, -y0, -z0) angle *= math.pi / 180 ca, sa = math.cos(angle), math.sin(angle) nca, nsa = math.cos(-angle), math.sin(-angle) return move( p.map( Transform('', '+*f%(ca)gY*f%(sa)gZ' % locals(), '+*f%(nsa)gY*f%(ca)gZ' % locals(), 'X', '+*f%(nca)gY*f%(nsa)gZ' % locals(), '+*f%(sa)gY*f%(nca)gZ' % locals())), 0, y0, z0)
def shear_cos_x_y(part, y0, y1, amp, off, t0, t1): dy = y1 - y0 t0 = math.radians(t0) t1 = math.radians(t1) # X' = X-(off+amp*math.cos(theta0+(theta1-theta0)*(Y-y0)/dy)) # X = X'+(off+amp*math.cos(theta0+(theta1-theta0)*(Y-y0)/dy)) return part.map( Transform( '-X+f%(off)g*f%(amp)gc+f%(t0)g/*-f%(t1)gf%(t0)g-Yf%(y0)gf%(dy)g' % locals(), 'Y', '+X+f%(off)g*f%(amp)gc+f%(t0)g/*-f%(t1)gf%(t0)g-Yf%(y0)gf%(dy)g' % locals(), 'Y'))
def shear_xy_z(part, zmin, zmax, dx0, dy0, dx1, dy1): dx = dx1 - dx0 dy = dy1 - dy0 dz = zmax - zmin # X' = X-dx0-dx*(Z-zmin)/dz # Y' = Y-dy0-dy*(Z-zmin)/dz # X = X'+dx0+(dx)*(Y-ymin)/dy # Y = Y'+dy0+(dy)*(Y-ymin)/dy return part.map( Transform('--Xf%(dx0)g/*f%(dx)g-Zf%(zmin)gf%(dz)g' % locals(), '--Yf%(dy0)g/*f%(dy)g-Zf%(zmin)gf%(dz)g' % locals(), '++Xf%(dx0)g/*f%(dx)g-Zf%(zmin)gf%(dz)g' % locals(), '++Yf%(dy0)g/*f%(dy)g-Zf%(zmin)gf%(dz)g' % locals()))
def repel(part, x, y, z, r): # Shift the part so that it is centered part = move(part, -x, -y, -z) # exponential fallout value # x*(1 - exp(-sqrt(x**2 + y**2 + z**2) / r)) d = '-f1xn/r++qXqYqZf%g' % r p = part.map(Transform('*X' + d, '*Y' + d, '*Z' + d, '', '', '')) b = r / math.e return move( Shape(p.math, part.bounds.xmin - b, part.bounds.ymin - b, part.bounds.zmin - b, part.bounds.xmax + b, part.bounds.ymax + b, part.bounds.zmax + b), x, y, z)
def scale_xyz(part, x0, y0, z0, sx, sy, sz): # X' = x0 + (X-x0)/sx # Y' = y0 + (Y-y0)/sy # Z' = z0 + (Z-z0)/sz # X = x0 + (X'-x0)*sx # Y = y0 + (Y'-y0)*sy # Z = z0 + (Z'-z0)*sz return part.map( Transform('+f%(x0)g/-Xf%(x0)gf%(sx)g' % locals(), '+f%(y0)g/-Yf%(y0)gf%(sy)g' % locals(), '+f%(z0)g/-Zf%(z0)gf%(sz)g' % locals(), '+f%(x0)g*-Xf%(x0)gf%(sx)g' % locals(), '+f%(y0)g*-Yf%(y0)gf%(sy)g' % locals(), '+f%(z0)g*-Zf%(z0)gf%(sz)g' % locals()))
def taper_x_y(part, x0, y0, y1, s0, s1): dy = y1 - y0 ds = s1 - s0 s0y1 = s0 * y1 s1y0 = s1 * y0 # X'=x0+(X-x0)*(y1-y0)/(Y*(s1-s0)+s0*y1-s1*y0)) # X=(X'-x0)*(Y*(s1-s0)+s0*y1-s1*y0)/(y1-y0)+x0 return part.map( Transform( '+f%(x0)g/*-Xf%(x0)gf%(dy)g-+*Yf%(ds)gf%(s0y1)gf%(s1y0)g' % locals(), 'Y', '+f%(x0)g*-Xf%(x0)g/-+*Yf%(ds)gf%(s0y1)gf%(s1y0)gf%(dy)g' % locals(), 'Y'))
def shear_cos_xy_z(part, z0, z1, ampx, offx, ampy, offy, t0, t1): dz = z1 - z0 t0 = math.radians(t0) t1 = math.radians(t1) # X' = X-(offx+ampx*math.cos(theta0+(theta1-theta0)*(Z-z0)/dz)) # X = X'+(offx+ampx*math.cos(theta0+(theta1-theta0)*(Z-z0)/dz)) # Y' = Y-(offy+ampy*math.cos(theta0+(theta1-theta0)*(Z-z0)/dz)) # Y = Y'+(offy+ampy*math.cos(theta0+(theta1-theta0)*(Z-z0)/dz)) return part.map( Transform( '-X+f%(offx)g*f%(ampx)gc+f%(t0)g/*-f%(t1)gf%(t0)g-Zf%(z0)gf%(dz)g' % locals(), '-Y+f%(offy)g*f%(ampy)gc+f%(t0)g/*-f%(t1)gf%(t0)g-Zf%(z0)gf%(dz)g' % locals(), 'Z', '+X+f%(offx)g*f%(ampx)gc+f%(t0)g/*-f%(t1)gf%(t0)g-Zf%(z0)gf%(dz)g' % locals(), '+Y+f%(offy)g*f%(ampy)gc+f%(t0)g/*-f%(t1)gf%(t0)g-Zf%(z0)gf%(dz)g' % locals(), 'Z'))
def scale_cos_xy_z(part, x0, y0, z0, z1, amp, off, t0, t1): dz = z1 - z0 t0 = math.radians(t0) t1 = math.radians(t1) # X' = x0 + (X-x0)/(off+amp*math.cos(theta0+(theta1-theta0)*(Z-z0)/dz)) # X = x0 + (X'-x0)*(off+amp*math.cos(theta0+(theta1-theta0)*(Z-z0)/dz)) # Y' = y0 + (Y-y0)/(off+amp*math.cos(theta0+(theta1-theta0)*(Z-z0)/dz)) # Y = y0 + (Y'-y0)*(off+amp*math.cos(theta0+(theta1-theta0)*(Z-z0)/dz)) return part.map( Transform( '/+f%(x0)g-Xf%(x0)g+f%(off)g*f%(amp)gc+f%(t0)g/*-f%(t1)gf%(t0)g-Zf%(z0)gf%(dz)g' % locals(), '/+f%(y0)g-Yf%(y0)g+f%(off)g*f%(amp)gc+f%(t0)g/*-f%(t1)gf%(t0)g-Zf%(z0)gf%(dz)g' % locals(), 'Z', '*+f%(x0)g-Xf%(x0)g+f%(off)g*f%(amp)gc+f%(t0)g/*-f%(t1)gf%(t0)g-Zf%(z0)gf%(dz)g' % locals(), '*+f%(y0)g-Yf%(y0)g+f%(off)g*f%(amp)gc+f%(t0)g/*-f%(t1)gf%(t0)g-Zf%(z0)gf%(dz)g' % locals(), 'Z'))
def taper_xy_z(part, x0, y0, z0, z1, s0, s1): dz = z1 - z0 # X' = x0 +(X-x0)*dz/(s1*(Z-z0) + s0*(z1-Z)) # Y' = y0 +(Y-y0)*dz/(s1*(Z-z0) + s0*(z1-Z)) # X = (X' - x0)*(s1*(Z-z0) + s0*(z1-Z))/dz + x0 # Y = (Y' - y0)*(s1*(Z-z0) + s0*(z1-Z))/dz + y0 return part.map( Transform( '+f%(x0)g/*-Xf%(x0)gf%(dz)g+*f%(s1)g-Zf%(z0)g*f%(s0)g-f%(z1)gZ' % locals(), '+f%(y0)g/*-Yf%(y0)gf%(dz)g+*f%(s1)g-Zf%(z0)g*f%(s0)g-f%(z1)gZ' % locals(), '', '+/*-Xf%(x0)g+*f%(s1)g-Zf%(z0)g*f%(s0)g-f%(z1)gZf%(dz)gf%(x0)g' % locals(), '+/*-Yf%(y0)g+*f%(s1)g-Zf%(z0)g*f%(s0)g-f%(z1)gZf%(dz)gf%(y0)g' % locals(), ''))
def twist_xy_z(part, x, y, z0, z1, t0, t1): # First, we'll move and scale so that the relevant part of the model # is at x=y=0 and scaled so that z is between 0 and 1. p1 = scale_z(move(part, -x, -y, -z0), 0, 1.0 / (z1 - z0)) t0 = math.pi * t0 / 180.0 t1 = math.pi * t1 / 180.0 # X' = X*cos(t1*z + t0*(1-z)) + Y*sin(t1*z + t0*(1-z)) # Y' = -X*sin(t1*z + t0*(1-z)) + Y*cos(t1*z + t0*(1-z)) # X = X*cos(t1*z + t0*(1-z)) - Y*sin(t1*z + t0*(1-z)) # Y = X*sin(t1*z + t0*(1-z)) + Y*cos(t1*z + t0*(1-z)) p2 = p1.map( Transform( '+*Xc+*f%(t1)gZ*f%(t0)g-f1Z*Ys+*f%(t1)gZ*f%(t0)g-f1Z' % locals(), '+n*Xs+*f%(t1)gZ*f%(t0)g-f1Z*Yc+*f%(t1)gZ*f%(t0)g-f1Z' % locals(), '-*Xc+*f%(t1)gZ*f%(t0)g-f1Z*Ys+*f%(t1)gZ*f%(t0)g-f1Z' % locals(), '+*Xs+*f%(t1)gZ*f%(t0)g-f1Z*Yc+*f%(t1)gZ*f%(t0)g-f1Z' % locals())) return move(scale_z(p2, 0, z1 - z0), x, y, z0)
def cylinder_y_wrap(part, radius): tx = "(X / %(radius)f)" % locals() tz = "(Z / %(radius)f)" % locals() dist = "(sqrt( (%(tx)s)**2 + (%(tz)s)**2 ))" % locals() angle = "(atan2( %(tx)s, %(tz)s ))" % locals() Xfn = "=%(angle)s * %(radius)f;" % locals() Yfn = "_" Zfn = "=(%(dist)s - 1) * %(radius)f;" % locals() angle = "(X / %(radius)f)" % locals() r = "(%(radius)f + Z)" % locals() sina = "(sin(%(angle)s))" % locals() cosa = "(cos(%(angle)s))" % locals() Xfn_inv = "=%(r)s * %(sina)s;" % locals() Yfn_inv = "" Zfn_inv = "=%(r)s * %(cosa)s;" % locals() return part.map(Transform(Xfn, Yfn, Zfn, Xfn_inv, Yfn_inv, Zfn_inv))
def move(part, dx, dy, dz=0): return part.map( Transform('-Xf%g' % dx, '-Yf%g' % dy, '-Zf%g' % dz, '+Xf%g' % dx, '+Yf%g' % dy, '+Zf%g' % dz))
def reflect_x(part, x0=0): # X' = 2*x0-X # X = 2*x0-X' return part.map(Transform('-*f2f%gX' % x0, '', '-*f2f%gX' % x0, ''))
def shear_x_z(part, z0, z1, dx0, dx1): # X' = X-dx0-(dx1-dx0)*(Z-z0)/(z1-z0) # X = X'+dx0+(dx1-dx0)*(Z-z0)/(z1-z0) return part.map( Transform('--Xf%(dx0)g/*f%(dx)g-Zf%(z0)gf%(dz)g' % locals(), '', '', '++Xf%(dx0))g/*f%(dx)g-Zf%(z0)gf%(dz)g' % locals(), '', ''))
def reflect_y(part, y0=0): # Y' = 2*y0-Y return part.map(Transform('', '-*f2f%gY' % y0, '', '-*f2f%gY' % y0))
def reflect_z(part, z0=0): # Z' = 2*z0-Z return part.map(Transform('', '', '-*f2f%gZ' % z0, '', '', '-*f2f%gZ' % z0))