# # spiral.py # test out different spiral styles. # from math import * import sys from string import * HUGE = 1e10 def startNewShape(): xpath.append([]) ypath.append([]) def addPoint(x, y): xpath[-1].append(x) ypath[-1].append(y) def addPointB(x, y): xpath[-1].insert(0, x) ypath[-1].insert(0, y) def boxEm(minX, maxX, minY, maxY, padding): startNewShape() addPoint(minX-padding, minY-padding) addPoint(minX-padding, maxY+padding) addPoint(maxX+padding, maxY+padding) addPoint(maxX+padding, minY-padding) addPoint(minX-padding, minY-padding) def addSpiralPoints(originX, originY, innerD, outerD, angle): addPoint(originX + cos(angle)*outerD, originY + sin(angle)*outerD) addPointB(originX + cos(angle)*innerD, originY + sin(angle)*innerD) RIGHT = 0 DOWN = 1 LEFT = 2 UP = 3 OVER_DOWN = 4 def spiralRow(originX, originY, traceWidth, blankWidth, centerSize, width, clockwise, endingDirection, tailLength, capEnd, numSpirals, padding): startNewShape() addPoint(originX - 0.5*width - 0.5*padding, originY - 0.7*width) addPoint(originX - 0.5*width - 0.5*padding, originY + 0.7*width) for i in range(0, numSpirals): spiral(originX, originY, traceWidth, blankWidth, centerSize, width, clockwise, endingDirection, tailLength, capEnd) #line for peeling better startNewShape() addPoint(originX + 0.5*width + 0.5*padding, originY - 0.7*width) addPoint(originX + 0.5*width + 0.5*padding, originY + 0.7*width) originX = originX + width + padding def dividerRow(originX, originY, traceWidth, blankWidth, centerSize, width, clockwise, endingDirection, tailLength, capEnd, center, edge, alwaysHoleDirection, numSpirals, padding): for i in range(0, numSpirals): divider(originX, originY, traceWidth, blankWidth, centerSize, width, clockwise, endingDirection, tailLength, capEnd, center, edge, alwaysHoleDirection) originX = originX + width + padding boxEm(centerX - 0.5* spiralDiameter, centerX + 0.5* spiralDiameter + padding + (numSpirals-1)*(width+padding), centerY-0.5* spiralDiameter, centerY+0.5* spiralDiameter, 0.2) def curve(centerX, centerY, radius, startingAngle, endingAngle, clockwise, close): if(clockwise): if(startingAngle > endingAngle): angleTraversed = endingAngle - startingAngle else: angleTraversed = endingAngle - startingAngle - 2*pi else: if(startingAngle < endingAngle): angleTraversed = endingAngle - startingAngle else: angleTraversed = endingAngle - startingAngle + 2*pi angleSteps = int(fabs(angleTraversed/(2*pi) * 30)) angleStep = angleTraversed/angleSteps angle = startingAngle print angle, angleStep, angleSteps, angleTraversed for i in range(0, angleSteps+1): addPoint(centerX + cos(angle)*radius, centerY + sin(angle)*radius) angle = angle + angleStep if(angle < 0): angle = 2*pi + angle if(angle > 2*pi): angle = angle - 2*pi if(close): addPoint(centerX + cos(startingAngle)*radius, centerY + sin(startingAngle)*radius) def divider(originX, originY, traceWidth, blankWidth, centerSize, width, clockwise, endingDirection, tailLength, capEnd, center, edge, alwaysHoleDirection): if(center): #boxEm(originX - centerSize/2.2, originX + centerSize/2.2, originY, originY + centerSize/2.5, centerSize * 0.1) startNewShape() curve(originX, originY - centerSize*0.1, centerSize/2.0 + blankWidth, 0, pi, False, True) spiral(originX, originY, traceWidth, blankWidth, centerSize, width, clockwise, alwaysHoleDirection, tailLength, False) spx = xpath.pop() spy = ypath.pop() innerX = spx[1] outerX = spx[-1] innerY = spy[1] outerY = spy[-1] if(innerX < outerX): minX = innerX maxX = outerX else: minX = outerX maxX = innerX if(innerY < outerY): minY = innerY maxY = outerY else: minY = outerY maxY = innerY dist = maxX - minX + maxY - minY if(alwaysHoleDirection == RIGHT): boxEm(maxX - dist/4.0, maxX, minY, maxY, dist*0.25) elif(alwaysHoleDirection == DOWN or alwaysHoleDirection == OVER_DOWN): boxEm(minX, maxX, maxY, maxY + dist/4.0, dist*0.25) elif(alwaysHoleDirection == LEFT): boxEm(maxX, maxX + dist/4.0, minY, maxY, dist*0.25) elif(alwaysHoleDirection == UP): boxEm(minX, maxX, maxY - dist/4.0, maxY, dist*0.25) if(not edge): return spiral(originX, originY, traceWidth, blankWidth, centerSize, width, clockwise, endingDirection, tailLength, False) spx = xpath.pop() spy = ypath.pop() innerX = spx[1] outerX = spx[-1] innerY = spy[1] outerY = spy[-1] if(innerX < outerX): minX = innerX maxX = outerX else: minX = outerX maxX = innerX if(innerY < outerY): minY = innerY maxY = outerY else: minY = outerY maxY = innerY dist = maxX - minX + maxY - minY if(endingDirection == RIGHT): boxEm(maxX - dist/4.0, maxX, minY, maxY, dist*0.25) elif(endingDirection == DOWN or endingDirection == OVER_DOWN): boxEm(minX, maxX, maxY, maxY + dist/4.0, dist*0.25) elif(endingDirection == LEFT): boxEm(maxX, maxX + dist/4.0, minY, maxY, dist*0.25) elif(endingDirection == UP): boxEm(minX, maxX, maxY - dist/4.0, maxY, dist*0.25) #0 is right. half circle covers centertop. def spiral(originX, originY, traceWidth, blankWidth, centerSize, width, clockwise, endingDirection, tailLength, capEnd): #numSteps = 720.0 numSteps = 45.0 totalSteps = 0 if(endingDirection == RIGHT): endingAngle = 0 elif(endingDirection == DOWN): endingAngle = 1.5*pi + pi/180.0 * 10 elif(endingDirection == LEFT): endingAngle = pi elif(endingDirection == UP): endingAngle = 0.5*pi elif(endingDirection == OVER_DOWN): endingAngle = 1.5*pi - pi/180.0 * 25 startNewShape() angleStep = (2*pi)/numSteps if(clockwise): angleStep = -angleStep angle = 0 if(clockwise): angle = pi dirMod = -1 if(clockwise): dirMod = 1 innerD = centerSize/2.0 - traceWidth while (clockwise and angle > 0) or (not clockwise and angle < pi): addPoint(originX + cos(angle)*(innerD+traceWidth), originY + sin(angle)*(innerD+traceWidth)) angle = angle + angleStep innerD = innerD + (traceWidth + blankWidth) / numSteps if(angle < 0): angle = 2*pi - angle if(angle > 2*pi): angle = angle - 2*pi while(not (fabs(endingAngle-angle)<(2*pi/numSteps) and ((innerD+traceWidth)>(0.5*width) or (innerD+traceWidth)>(0.5*width)))): addSpiralPoints(originX, originY, innerD, innerD+traceWidth, angle) angle = angle + angleStep if(angle < 0): angle = 2*pi + angle if(angle > 2*pi): angle = angle - 2*pi innerD = innerD + (traceWidth + blankWidth) / numSteps totalSteps = totalSteps + 1 #print "NOT (", fabs(endingDirection-angle), "<", (1/numSteps), ") AND (", fabs(originX-(innerD+traceWidth)), ">", 0.5*width, ")" print totalSteps / numSteps, " Loops" #extend inner for connection for i in range(1,int(ceil(traceWidth*3.5/(innerD*pi*2/numSteps)))+1): addPointB(originX + cos(angle)*(innerD), originY + sin(angle)*(innerD)) angle = angle + angleStep if(angle < 0): angle = 2*pi + angle if(angle > 2*pi): angle = angle - 2*pi innerD = innerD + (traceWidth + blankWidth) / numSteps xInner = xpath[-1][0] yInner = ypath[-1][0] xOuter = xpath[-1][-1] yOuter = ypath[-1][-1] if(endingDirection == RIGHT): xOuter = xOuter + tailLength xInner = xInner + tailLength + traceWidth yInner = yInner - dirMod*(0.06 - traceWidth) yOuter = yOuter - dirMod*(0.03 - traceWidth) elif(endingDirection == DOWN or endingDirection == OVER_DOWN): yOuter = yOuter - tailLength yInner = yInner - tailLength - traceWidth xInner = xInner - dirMod*(0.06 - traceWidth) xOuter = xOuter - dirMod*(0.03 - traceWidth) elif(endingDirection == LEFT): xOuter = xOuter - tailLength xInner = xInner - tailLength - traceWidth yInner = yInner + dirMod*(0.06 - traceWidth) yOuter = yOuter + dirMod*(0.03 - traceWidth) elif(endingDirection == UP): yOuter = yOuter + tailLength yInner = yInner + tailLength + traceWidth xInner = xInner + dirMod*(0.06 - traceWidth) xOuter = xOuter + dirMod*(0.03 - traceWidth) addPoint(xOuter, yOuter) addPointB(xInner, yInner) if(capEnd): addPoint(xInner, yInner) #add cut for helpful peeling dx = xpath[-1][0] - xpath[-1][1] dy = ypath[-1][0] - ypath[-1][1] addPointB(xInner + dx, yInner+dy) #origin is minX, minY. def squareSpiral(originX, originY, traceWidth, blankWidth, centerSize, width, clockwise, endingDirection, tailLength, capEnd): xpath.append([]) ypath.append([]) dirMod = 1 if(not clockwise): dirMod = -1 innerLength = centerSize + blankWidth - traceWidth centerSizeY = (innerLength + (traceWidth + blankWidth) / 2.0) - blankWidth * 2 #draw middle. come out top xpath[-1].append(originX - dirMod*0.5*centerSize) ypath[-1].append(originY + 0.5*centerSizeY) xpath[-1].append(originX - dirMod*0.5*centerSize) ypath[-1].append(originY - 0.5*centerSizeY) xpath[-1].append(originX + dirMod*0.5*centerSize) ypath[-1].append(originY - 0.5*centerSizeY) xpath[-1].append(originX + dirMod*0.5*centerSize) ypath[-1].append(originY + 0.5*centerSizeY) xpath[-1].append(originX - dirMod*(0.5*centerSize - traceWidth)) ypath[-1].append(originY + 0.5*centerSizeY) #first short chunk xInner = originX - dirMod*(0.5*centerSize - traceWidth) yInner = originY + 0.5*centerSizeY + blankWidth xpath[-1].append(xInner) ypath[-1].append(yInner) xOuter = originX - dirMod*(0.5*centerSize) yOuter = originY + 0.5*centerSizeY + blankWidth + traceWidth xpath[-1].insert(0, xOuter) ypath[-1].insert(0, yOuter) numsegments = 0 direction = -1; while(not (endingDirection == direction and (fabs(originX-xOuter) > 0.5*width or fabs(originY-yOuter) > 0.5*width))): direction = (direction + 1) % 4 if(direction == 0): #right xInner = xInner + dirMod*innerLength xOuter = xOuter + dirMod*(innerLength + 2*traceWidth) elif(direction == 1): #down yInner = yInner - innerLength yOuter = yOuter - innerLength - 2*traceWidth elif(direction == 2): #left xInner = xInner - dirMod*innerLength xOuter = xOuter - dirMod*(innerLength + 2*traceWidth) elif(direction == 3): #up yInner = yInner + innerLength yOuter = yOuter + innerLength + 2*traceWidth xpath[-1].append(xInner) ypath[-1].append(yInner) xpath[-1].insert(0, xOuter) ypath[-1].insert(0, yOuter) innerLength += (traceWidth + blankWidth) / 2.0 numsegments = numsegments + 1 print (numsegments/4), "turns." if(endingDirection == 0): #right xOuter = xOuter + tailLength xInner = xInner + tailLength + traceWidth yInner = yInner + dirMod*(0.018 - traceWidth) elif(endingDirection == 1): #down yOuter = yOuter - tailLength yInner = yInner - tailLength - traceWidth xInner = xInner - dirMod*(0.018 - traceWidth) elif(endingDirection == 2): #left xOuter = xOuter - tailLength xInner = xInner - tailLength - traceWidth yInner = yInner - dirMod*(0.018 - traceWidth) elif(endingDirection == 3): #up yOuter = yOuter + tailLength yInner = yInner + tailLength + traceWidth xInner = xInner + dirMod*(0.018 - traceWidth) xpath[-1].append(xInner) ypath[-1].append(yInner) xpath[-1].insert(0, xOuter) ypath[-1].insert(0, yOuter) if(capEnd): xpath[-1].append(xOuter) ypath[-1].append(yOuter) def svgwrite(xpath,ypath,filename): xmin = HUGE ymin = HUGE xmax = -HUGE ymax = -HUGE for piece in range(len(xpath)): for point in range(len(xpath[piece])): x = xpath[piece][point] y = ypath[piece][point] if (x < xmin): xmin = x if (x > xmax): xmax = x if (y < ymin): ymin = y if (y > ymax): ymax = y outfile = open(filename,"w") outfile.write('\n') outfile.write('\n') outfile.write('\n'\ %(xmax-xmin,ymax-ymin,xmin,ymin,xmax-xmin,ymax-ymin)) outfile.write('\n') for piece in range(len(xpath)): outfile.write('\n') outfile.write('\n') outfile.write('\n') outfile.close() x = 0 y = 0 xpath = [] ypath = [] def testIt(): originX = 0 originY = 0 outfile = "out.svg" copper_width = 0.02 space_width = 0.02 #0.15 #.022 spiralDiameter = 0.8 middleSize = 0.15 #0.1 tailLength = 0.1 endingDirection = DOWN clockwise = True cap = True centerX = 0 centerY = 0 centerHole = True edgeHole = True spiralPadding = 0.07 numBottomRow = 0 if(numBottomRow > 0): endingDirection = DOWN clockwise = True spiralRow(centerX, centerY, copper_width, space_width, middleSize, spiralDiameter, clockwise, endingDirection, tailLength, cap, numBottomRow, spiralPadding) numBottomDivider = 0 if(numBottomDivider > 0): endingDirection = DOWN clockwise = True centerHole = True edgeHole = False dividerRow(centerX, centerY, copper_width, space_width, middleSize, spiralDiameter, clockwise, endingDirection, tailLength, cap, centerHole, edgeHole, DOWN, numBottomDivider, spiralPadding) numSecondRow = 0 if(numSecondRow > 0): endingDirection = UP clockwise = False spiralRow(centerX, centerY, copper_width, space_width, middleSize, spiralDiameter, clockwise, endingDirection, tailLength, cap, numSecondRow, spiralPadding) numSecondDivider = 0 if(numSecondDivider > 0): endingDirection = UP clockwise = False centerHole = False edgeHole = True dividerRow(centerX, centerY, copper_width, space_width, middleSize, spiralDiameter, clockwise, endingDirection, tailLength, cap, centerHole, edgeHole, DOWN, numSecondDivider, spiralPadding) numThirdRow = 0 if(numThirdRow > 0): endingDirection = UP clockwise = True spiralRow(centerX, centerY, copper_width, space_width, middleSize, spiralDiameter, clockwise, endingDirection, tailLength, cap, numThirdRow, spiralPadding) numThirdDivider = 0 if(numThirdDivider > 0): endingDirection = UP clockwise = True centerHole = True edgeHole = False dividerRow(centerX, centerY, copper_width, space_width, middleSize, spiralDiameter, clockwise, endingDirection, tailLength, cap, centerHole, edgeHole, DOWN, numThirdDivider, spiralPadding) numTopRow = 0 if(numTopRow > 0): endingDirection = OVER_DOWN clockwise = False spiralRow(centerX, centerY, copper_width, space_width, middleSize, spiralDiameter, clockwise, endingDirection, tailLength, cap, numTopRow, spiralPadding) numTopDivider = 0 if(numTopDivider > 0): endingDirection = OVER_DOWN clockwise = False centerHole = False edgeHole = True dividerRow(centerX, centerY, copper_width, space_width, middleSize, spiralDiameter, clockwise, endingDirection, tailLength, cap, centerHole, edgeHole, DOWN, numTopDivider, spiralPadding) squareSpiral(0, 0, copper_width, space_width, middleSize, spiralDiameter, clockwise, endingDirection, tailLength, cap) #spiral(centerX, centerY, copper_width, space_width, middleSize, spiralDiameter, clockwise, endingDirection, tailLength, cap) #endingDirection = UP #spiral(centerX, centerY, copper_width, space_width, middleSize, spiralDiameter, clockwise, endingDirection, tailLength, cap) #divider(centerX, centerY, copper_width, space_width, middleSize, spiralDiameter, clockwise, endingDirection, tailLength, cap, centerHole, edgeHole, DOWN) #padding = 0.05 #boxEm(centerX - 0.5* spiralDiameter, centerX + 0.5* spiralDiameter, centerY-0.5* spiralDiameter - 0.1, centerY+0.5* spiralDiameter + 0.1, padding) svgwrite(xpath,ypath,"out.svg") print "Spirals written to out.svg"