import math
 
def pytha(c,b):
    value = math.sqrt(c*c - b*b)
    return value

#location of slot
xpos = 40
ypos = 0

# size in mm
mill = 0.6
cir1 = 5.3 
cir2 = 6.3 
cir3 = 2.3 
ycr3 = 4.0 
min1 = 0.05

step = 4 # degrees

# position
xhole1 = 0.0
yhole1 = 6.0
xhole2 = -4.0 # top mill
yhole2 = 3.0

# size solder holes
xhole = 1.5 
yhole = 0.8   

#pcb height
zmax = -22

#diode
dxsize = 2.5
dysize = 7.5 - dxsize


def pytha(c,b):
    value = math.sqrt(c*c - b*b)
    return value


def pcbmillcherry(xpos,ypos):

    c1 = ((cir1 - min1)/ 2) - (mill /2) 
    c2 = ((cir2 - min1)/ 2) - (mill /2)
    c3 = ((cir3 - min1)/ 2) - (mill /2)
    y3 = ycr3
    x =  round (math.degrees(math.atan(c3/(pytha(c2, c3)))))
    
    print ('G00 Z5.0')
    print ('G00 X{0:.4f} Y{1:.4f}' .format( xpos - c3, ypos + pytha(c1, c3)))
    for z in range (-2, zmax, -2):
        print ('G01 F50')
        print ('G01 Z{0:.4f}' .format(z/10))
    
        print ('G01 F50')
    
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - c3, ypos + pytha(c1, c3)))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - c3, ypos + y3))
        
        for i in range (-90,90,step*3):
            print ('G01 X{0:.4f} Y{1:.4f}' .format(xpos + c3 * math.sin(math.radians(i)) , ypos + y3 + c3 * math.cos(math.radians(i))))
        
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + c3, ypos + y3))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + c3, ypos + pytha(c1, c3)  ))
        
        for i in range (15,75,step):
            print ('G01 X{0:.4f} Y{1:.4f}' .format(xpos + c1 * math.sin(math.radians(i)) , ypos + c1 * math.cos(math.radians(i))))
        
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + pytha(c1, c3), ypos + c3))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + pytha(c2, c3), ypos + c3))
        
        for i in range (90-x,90+x, step):
            print ('G01 X{0:.4f} Y{1:.4f}' .format(xpos + c2 * math.sin(math.radians(i)) , ypos + c2 * math.cos(math.radians(i))))
        
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + pytha(c2, c3), ypos - c3))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + pytha(c1, c3), ypos - c3))
        
        for i in range (15+90,75+90,step):
            print ('G01 X{0:.4f} Y{1:.4f}' .format(xpos + c1 * math.sin(math.radians(i)) , ypos + c1 * math.cos(math.radians(i))))
        
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + c3, ypos - pytha(c1, c3)))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + c3, ypos - pytha(c2, c3)))
        
        for i in range (180-x,180+x, step):
            print ('G01 X{0:.4f} Y{1:.4f}' .format(xpos + c2 * math.sin(math.radians(i)) , ypos + c2 * math.cos(math.radians(i))))
        
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - c3, ypos - pytha(c2, c3)))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - c3, ypos - pytha(c1, c3)))
        
        for i in range (15+180,75+180,step):
            print ('G01 X{0:.4f} Y{1:.4f}' .format(xpos + c1 * math.sin(math.radians(i)) , ypos + c1 * math.cos(math.radians(i))))
        
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - pytha(c1, c3), ypos - c3))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - pytha(c2, c3), ypos - c3))
        
        for i in range (270-x,270+x, step):
            print ('G01 X{0:.4f} Y{1:.4f}' .format(xpos + c2 * math.sin(math.radians(i)) , ypos + c2 * math.cos(math.radians(i))))
        
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - pytha(c2, c3), ypos + c3))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - pytha(c1, c3), ypos + c3))
        
        for i in range (15+270,75+270,step):
            print ('G01 X{0:.4f} Y{1:.4f}' .format(xpos + c1 * math.sin(math.radians(i)) , ypos + c1 * math.cos(math.radians(i))))
        
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - c3, ypos + pytha(c1, c3)  ))
    
    c1 = (cir1 / 2) - (mill /2) 
    c2 = (cir2 / 2) - (mill /2)
    c3 = (cir3 / 2) - (mill /2)
    y3 = ycr3
    x =  round (math.degrees(math.atan(c3/(pytha(c2, c3)))))
    
    print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - c3, ypos + pytha(c1, c3)))
    print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - c3, ypos + y3))
    
    for i in range (-90,90,step*3):
        print ('G01 X{0:.4f} Y{1:.4f}' .format(xpos + c3 * math.sin(math.radians(i)) , ypos + y3 + c3 * math.cos(math.radians(i))))
    
    print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + c3, ypos + y3))
    print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + c3, ypos + pytha(c1, c3)  ))
    
    for i in range (15,75,step):
        print ('G01 X{0:.4f} Y{1:.4f}' .format(xpos + c1 * math.sin(math.radians(i)) , ypos + c1 * math.cos(math.radians(i))))
    
    print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + pytha(c1, c3), ypos + c3))
    print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + pytha(c2, c3), ypos + c3))
    
    for i in range (90-x,90+x, step):
        print ('G01 X{0:.4f} Y{1:.4f}' .format(xpos + c2 * math.sin(math.radians(i)) , ypos + c2 * math.cos(math.radians(i))))
    
    print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + pytha(c2, c3), ypos - c3))
    print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + pytha(c1, c3), ypos - c3))
    
    for i in range (15+90,75+90,step):
        print ('G01 X{0:.4f} Y{1:.4f}' .format(xpos + c1 * math.sin(math.radians(i)) , ypos + c1 * math.cos(math.radians(i))))
    
    print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + c3, ypos - pytha(c1, c3)))
    print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + c3, ypos - pytha(c2, c3)))
    
    for i in range (180-x,180+x, step):
        print ('G01 X{0:.4f} Y{1:.4f}' .format(xpos + c2 * math.sin(math.radians(i)) , ypos + c2 * math.cos(math.radians(i))))
    
    print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - c3, ypos - pytha(c2, c3)))
    print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - c3, ypos - pytha(c1, c3)))
    
    for i in range (15+180,75+180,step):
        print ('G01 X{0:.4f} Y{1:.4f}' .format(xpos + c1 * math.sin(math.radians(i)) , ypos + c1 * math.cos(math.radians(i))))
    
    print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - pytha(c1, c3), ypos - c3))
    print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - pytha(c2, c3), ypos - c3))
    
    for i in range (270-x,270+x, step):
        print ('G01 X{0:.4f} Y{1:.4f}' .format(xpos + c2 * math.sin(math.radians(i)) , ypos + c2 * math.cos(math.radians(i))))
    
    print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - pytha(c2, c3), ypos + c3))
    print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - pytha(c1, c3), ypos + c3))
    
    for i in range (15+270,75+270,step):
        print ('G01 X{0:.4f} Y{1:.4f}' .format(xpos + c1 * math.sin(math.radians(i)) , ypos + c1 * math.cos(math.radians(i))))
    
    print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - c3, ypos + pytha(c1, c3)  ))
    print ('G00 Z5.0')
    
    xh = (xhole - mill)/2
    yh = (yhole - mill)/2
    
    print ('G00 X{0:.4f} Y{1:.4f}' .format( xpos + xhole1 + xh, ypos + yhole1 + yh))
    for z in range (-2, zmax, -2):
        print ('G01 F50')
        print ('G01 Z{0:.4f}' .format(z/10))
        print ('G01 F50')
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole1 + xh, ypos + yhole1 + yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole1 - xh, ypos + yhole1 + yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole1 - xh, ypos + yhole1 - yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole1 + xh, ypos + yhole1 - yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole1 + xh, ypos + yhole1 + yh))
    print ('G00 Z5.0')


    for z in range (-2,-6, -2):
        print ('G01 F50')
        print ('G01 Z{0:.4f}' .format(z/10))
        print ('G01 F50')

        xh = (mill * 0.5) + (xhole - mill)/2 
        yh = (mill * 0.5) + (yhole - mill)/2
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole1 + xh, ypos + yhole1 + yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole1 - xh, ypos + yhole1 + yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole1 - xh, ypos + yhole1 - yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole1 + xh, ypos + yhole1 - yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole1 + xh, ypos + yhole1 + yh))

        xh = (mill * 1.0) + (xhole - mill)/2 
        yh = (mill * 1.0) + (yhole - mill)/2
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole1 + xh, ypos + yhole1 + yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole1 - xh, ypos + yhole1 + yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole1 - xh, ypos + yhole1 - yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole1 + xh, ypos + yhole1 - yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole1 + xh, ypos + yhole1 + yh))

        xh = (mill * 1.5) + (xhole - mill)/2 
        yh = (mill * 1.5) + (yhole - mill)/2
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole1 + xh, ypos + yhole1 + yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole1 - xh, ypos + yhole1 + yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole1 - xh, ypos + yhole1 - yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole1 + xh, ypos + yhole1 - yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole1 + xh, ypos + yhole1 + yh))
    print ('G00 Z5.0')



    
    xh = (xhole - mill)/2
    yh = (yhole - mill)/2
    
    print ('G00 X{0:.4f} Y{1:.4f}' .format( xpos + xhole2 + xh, ypos + yhole2 + yh))
    for z in range (-2, zmax, -2):
        print ('G01 F50')
        print ('G01 Z{0:.4f}' .format(z/10))
        print ('G01 F50')
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole2 + xh, ypos + yhole2 + yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole2 - xh, ypos + yhole2 + yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole2 - xh, ypos + yhole2 - yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole2 + xh, ypos + yhole2 - yh))
    print ('G00 Z5.0')

    for z in range (-2,-6, -2):
        print ('G01 F50')
        print ('G01 Z{0:.4f}' .format(z/10))
        print ('G01 F50')

        xh = (mill * 0.5) + (xhole - mill)/2 
        yh = (mill * 0.5) + (yhole - mill)/2
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole2 + xh, ypos + yhole2 + yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole2 - xh, ypos + yhole2 + yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole2 - xh, ypos + yhole2 - yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole2 + xh, ypos + yhole2 - yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole2 + xh, ypos + yhole2 + yh))

        xh = (mill * 1.0) + (xhole - mill)/2 
        yh = (mill * 1.0) + (yhole - mill)/2
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole2 + xh, ypos + yhole2 + yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole2 - xh, ypos + yhole2 + yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole2 - xh, ypos + yhole2 - yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole2 + xh, ypos + yhole2 - yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole2 + xh, ypos + yhole2 + yh))

        xh = (mill * 1.5) + (xhole - mill)/2 
        yh = (mill * 1.5) + (yhole - mill)/2
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole2 + xh, ypos + yhole2 + yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole2 - xh, ypos + yhole2 + yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole2 - xh, ypos + yhole2 - yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole2 + xh, ypos + yhole2 - yh))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + xhole2 + xh, ypos + yhole2 + yh))
    print ('G00 Z5.0')


def pcbmilldiode(xpos,ypos):

    dx = (dxsize - mill ) / 2.0
    dy = (dysize - mill ) / 2.0
    dc = dx
 
    print ('G00 Z5.0')
    print ('G00 X{0:.4f} Y{1:.4f}' .format( xpos - dx, ypos + dy))
    for z in range (-2, zmax, -2):

        print ('G01 Z{0:.4f}' .format(z/10))

        for i in range (-90,90,step*3):
            print ('G01 X{0:.4f} Y{1:.4f}' .format(xpos + dc * math.sin(math.radians(i)) , ypos + dy + dc * math.cos(math.radians(i))))

        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + dx, ypos + dy))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + dx, ypos - dy))

        for i in range (90,270,step*3):
            print ('G01 X{0:.4f} Y{1:.4f}' .format(xpos + dc * math.sin(math.radians(i)) , ypos - dy + dc * math.cos(math.radians(i))))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - dx, ypos - dy))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - dx, ypos + dy))
    print ('G00 Z5.0')

def pcbmilldioderotate (xpos,ypos):

    dx = (dysize - mill ) / 2.0 # rotated
    dy = (dxsize - mill ) / 2.0
    dc = dy
 
    print ('G00 Z5.0')
    print ('G00 X{0:.4f} Y{1:.4f}' .format( xpos - dx, ypos - dy))
    for z in range (-2, zmax, -2):

        print ('G01 Z{0:.4f}' .format(z/10))

        for i in range (180,360,step*3):
            print ('G01 X{0:.4f} Y{1:.4f}' .format(xpos - dx + dc * math.sin(math.radians(i)) , ypos + dc * math.cos(math.radians(i))))

        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - dx, ypos + dy))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + dx, ypos + dy))

        for i in range (0,180,step*3):
            print ('G01 X{0:.4f} Y{1:.4f}' .format(xpos + dx + dc * math.sin(math.radians(i)) , ypos + dc * math.cos(math.radians(i))))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos + dx, ypos - dy))
        print ('G01 X{0:.4f} Y{1:.4f}' .format( xpos - dx, ypos - dy))
    print ('G00 Z5.0')

 
print ('G00 F50')
print ('G01 F50')


pcbmillcherry (35.71875  ,88.10625)
pcbmillcherry (54.76875  ,88.10625)
pcbmillcherry (73.81875  ,88.10625)
pcbmillcherry (92.86875  ,88.10625)
pcbmillcherry (111.91875 ,88.10625)
pcbmillcherry (130.96875 ,88.10625)
pcbmillcherry (150.01875 ,88.10625)
pcbmillcherry (14.2875   ,69.05625)
pcbmillcherry (40.48125  ,69.05625)
pcbmillcherry (64.29375  ,69.05625)
pcbmillcherry (83.34375  ,69.05625)
pcbmillcherry (102.39375 ,69.05625)
pcbmillcherry (121.44375 ,69.05625)
pcbmillcherry (140.49375 ,69.05625)
pcbmillcherry (14.2875   ,50.00625)
pcbmillcherry (42.8625   ,50.00625)
pcbmillcherry (69.05625  ,50.00625)
pcbmillcherry (88.10625  ,50.00625)
pcbmillcherry (107.15625 ,50.00625)
pcbmillcherry (126.20625 ,50.00625)
pcbmillcherry (145.25625 ,50.00625)
pcbmillcherry (14.2875   ,30.95625)
pcbmillcherry (35.625    ,30.95625)
pcbmillcherry (59.625    ,30.95625)
pcbmillcherry (78.58125  ,30.95625)
pcbmillcherry (97.63125  ,30.95625)
pcbmillcherry (116.68125 ,30.95625)
pcbmillcherry (135.73125 ,30.95625)
pcbmillcherry (154.78125 ,30.95625)
pcbmillcherry (14.2875   ,11.90625)
pcbmillcherry (38.1      ,11.90625)
pcbmillcherry (61.9125   ,11.90625)
pcbmillcherry (85.725    ,11.90625)
pcbmillcherry (109.5375  ,11.90625)
pcbmillcherry (138.1125  ,11.90625)



pcbmilldiode (26.19375   ,84.93125) 
pcbmilldiode (45.24375   ,84.93125) 
pcbmilldiode (64.29375   ,84.93125) 
pcbmilldiode (83.34375   ,84.93125) 
pcbmilldiode (102.39375  ,84.93125) 
pcbmilldiode (121.44375  ,84.93125) 
pcbmilldiode (140.49375  ,84.93125) 
pcbmilldiode (23.8125    ,65.88125) 
pcbmilldiode (30.95625   ,65.88125) 
pcbmilldiode (54.76875   ,65.88125) 
pcbmilldiode (73.81875   ,65.88125) 
pcbmilldiode (92.86875   ,65.88125) 
pcbmilldiode (111.91875  ,65.88125) 
pcbmilldiode (130.96875  ,65.88125) 
pcbmilldiode (23.8125    ,46.83125) 
pcbmilldiode (33.3375    ,46.83125) 
pcbmilldiode (59.53125   ,46.83125) 
pcbmilldiode (78.58125   ,46.83125) 
pcbmilldiode (97.63125   ,46.83125) 
pcbmilldiode (116.68125  ,46.83125) 
pcbmilldiode (135.73125  ,46.83125) 
pcbmilldiode (23.8125    ,27.78125) 
pcbmilldiode (50.1       ,27.78125) 
pcbmilldiode (69.05625   ,27.78125) 
pcbmilldiode (88.10625   ,27.78125) 
pcbmilldiode (107.15625  ,27.78125) 
pcbmilldiode (126.20625  ,27.78125) 
pcbmilldiode (145.25625  ,27.78125) 
pcbmilldiode (28.575     ,8.73125 )
pcbmilldiode (52.3875    ,8.73125 )
pcbmilldiode (76.2       ,8.73125 )
pcbmilldiode (100.0125   ,8.73125 )
pcbmilldiode (128.5875   ,8.73125 )

pcbmilldioderotate (14.2875, 21.43125)

print ('G00 X0 Y0 Z5')
