#
# heart.cad
#

#
# define limits and parameters
#
cad_xmin = -.5
cad_xmax = .5
cad_ymin = -.6
cad_ymax = .4
cad_units = 'in' # coordinates units
cad_bit_depth = '1' # bit depth
cad_npts = 500
cad_nx = cad_npts # x points to render
cad_ny = cad_npts # y points to render

#
# define shapes and transformation
#
# circle(x0, y0, r)
# cylinder(x0, y0, z0, z1, r)
# sphere(x0, y0, z0, r)
# torus(x0, y0, z0, r0, r1)
# rectangle(x0, x1, y0, y1)
# cube(x0, x1, y0, y1, z0, z1)
# union(part1, part2)
# intersect(part1, part2)
# subtract(part1, part2)
# translate(part,dx,dy,dz)
# rotate_x(part, theta)
# rotate_y(part, theta)
# rotate_z(part, theta)
# reflect_x(part, x0)
# reflect_y(part, y0)
# reflect_z(part, z0)
# (many more to come)

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 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 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 union(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 subtract(part1, part2):
   part = "(part1) & ~(part2)"
   part = replace(part,'part1',part1)
   part = replace(part,'part2',part2)
   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_x(part, theta):
   part = replace(part,'Y','(cos(theta)*Y+sin(theta)*z)')
   part = replace(part,'Z','(-sin(theta)*Y+cos(theta)*z)')
   part = replace(part,'z','Z')
   part = replace(part,'theta',str(theta))
   return part

def rotate_y(part, theta):
   part = replace(part,'X','(cos(theta)*X+sin(theta)*z)')
   part = replace(part,'Z','(-sin(theta)*X+cos(theta)*z)')
   part = replace(part,'z','Z')
   part = replace(part,'theta',str(theta))
   return part

def rotate_z(part, theta):
   part = replace(part,'X','(cos(theta)*X+sin(theta)*y)')
   part = replace(part,'Y','(-sin(theta)*X+cos(theta)*y)')
   part = replace(part,'y','Y')
   part = replace(part,'theta',str(theta))
   return part

def reflect_x(part, x0):
   part = replace(part,'X','(x0-X)')
   part = replace(part,'x0',str(x0))
   return part

def reflect_y(part, y0):
   part = replace(part,'Y','(y0-Y)')
   part = replace(part,'y0',str(y0))
   return part

def reflect_z(part, z0):
   part = replace(part,'Z','(z0-Z)')
   part = replace(part,'z0',str(z0))
   return part

#
# define part
#


leftside = circle(0.15,0,.5)
leftside = subtract(leftside,rectangle(-1,1,0,1))
leftside = subtract(leftside,rectangle(0,1,-1,1))
leftside = union(leftside,circle(-.15,0,.2))
rightside = reflect_x(leftside,0)
heart = union(leftside,rightside)
hole = circle(0,0.05,.03)
heart = subtract(heart,hole)

#
# assign part to SAT_function
#

SAT_function = heart





