//Spiral Notes //------------------------------------------------------------------- //Height = center to center height of the end spheres which form the spirals. Ends will need to be flattened by the user as desired. Actual height of the rendering is Height+2*baseRadius //Radius = the maximum distance from the axis of the spiral (the z axis) to the center of the sphere(s) forming the spiral //baseRadius = cross sectional radius of the spiral //frequency = the number of complete revolutions about the axis made by the spiral, whole numbers will result in spirals whose tops end directly above their bases //resolution = integer number of spheres, not to be confused with $fn. The greater the number of spheres, the smoother the spiral will be (also longer render times!). Recommended that this number be 8*frequency or greater. //numSpirals = integer number of spirals used in the spiralMulti modules spaced evenly around the axis (3 spirals are spaced 120 degrees apart, 4 spirals: 90 degrees apart, etc.) //Instructions //------------------------------------------------------------------ //1. Place spiral.scad in the "libraries" folder of your openscad installation. Find the libraries folder by File -> Show Library Folder... //2. Then create a new or open one of your existing scad files and include spiral.scad with the following code: //use; //3. Then call the modules in your files with code similar to the following: //spiral(20,20,3,1,25); //spiralCone(20,20,3,1,25); //spiralEllipse(20,20,3,1,25); //spiralMulti(20,20,3,1,25,3); //spiralMultiCone(20,20,3,1,25,3); //spiralMultiEllipse(40,60,3,1,32,3); //------------------------------------------------------------- //simple spiral module spiral (height = 20, Radius = 20, baseRadius = 3, frequency = 1, resolution = 25, $fn=50) { union(){ translate ([0,0,-(height/2)]) { for(i=[0:resolution-2]){ hull(){ rotate ([0,0,frequency*360/(resolution-1)*i]) translate ([Radius,0,i*height/(resolution-1)]) sphere(r=baseRadius, center=true); rotate ([0,0,frequency*360/(resolution-1)*(i+1)]) translate ([Radius,0,(i+1)*height/(resolution-1)]) sphere(r=baseRadius,center=true); } } } } } //cone spiral module spiralCone(height=20,Radius=20,baseRadius=3,frequency=1,resolution=25, $fn=50) { union(){ translate ([0,0,-(height/2)]) { for(i=[0:resolution-2]){ hull(){ rotate ([0,0,frequency*360/(resolution-1)*i]) translate ([Radius-(i-1)*Radius/resolution,0,i*height/(resolution-1)]) sphere(r=baseRadius, center=true); rotate ([0,0,frequency*360/(resolution-1)*(i+1)]) translate ([Radius-i*Radius/resolution,0,(i+1)*height/(resolution-1)]) sphere(r=baseRadius,center=true); } } } } } //ellipse spiral module spiralEllipse(height=20,Radius=20,baseRadius=3,frequency=1,resolution=25, $fn=50) { union(){ translate ([0,0,-(height/2)]) { for(i=[0:resolution-2]){ hull(){ rotate ([0,0,frequency*360/(resolution-1)*i]) translate ([Radius*sqrt(1-(i/(resolution-1)*(i/(resolution-1)))),0,i*height/(resolution-1)]) sphere(r=baseRadius, center=true); rotate ([0,0,frequency*360/(resolution-1)*(i+1)]) translate ([Radius*sqrt(1-((i+1)/(resolution-1)*((i+1)/(resolution-1)))),0,(i+1)*height/(resolution-1)]) sphere(r=baseRadius,center=true); } } } } } // Multiple spirals arranged radially around the axis module spiralMulti(height=20,Radius=20,baseRadius=3,frequency=1,resolution=25,numSpirals=3,$fn=50) { shiftAngle=360/numSpirals; for(total=[0:numSpirals-1]) { union(){ translate ([0,0,-(height/2)]) { for(i=[0:resolution-2]){ hull(){ rotate ([0,0,frequency*360/(resolution-1)*i+shiftAngle*total]) translate ([Radius,0,i*height/(resolution-1)]) sphere(r=baseRadius, center=true); rotate ([0,0,frequency*360/(resolution-1)*(i+1)+shiftAngle*total]) translate ([Radius,0,(i+1)*height/(resolution-1)]) sphere(r=baseRadius,center=true); } } } } } } // Multiple spirals arranged radially around the axis tapering in towards the axis module spiralMultiCone(height=20,Radius=20,baseRadius=3,frequency=1,resolution=25,numSpirals=3,$fn=50) { shiftAngle=360/numSpirals; for(total=[0:numSpirals-1]) { union(){ translate ([0,0,-(height/2)]) { for(i=[0:resolution-2]){ hull(){ rotate ([0,0,frequency*360/(resolution-1)*i+shiftAngle*total]) translate ([Radius-(i-1)*Radius/resolution,0,i*height/(resolution-1)]) sphere(r=baseRadius, center=true); rotate ([0,0,frequency*360/(resolution-1)*(i+1)+shiftAngle*total]) translate ([Radius-i*Radius/resolution,0,(i+1)*height/(resolution-1)]) sphere(r=baseRadius,center=true); } } } } } } //multiple ellipse spiral module spiralMultiEllipse(height=20,Radius=20,baseRadius=3,frequency=1,resolution=25,numSpirals=3,$fn=50) { shiftAngle=360/numSpirals; for(total=[0:numSpirals-1]) { union(){ translate ([0,0,-(height/2)]) { for(i=[0:resolution-2]){ hull(){ rotate ([0,0,frequency*360/(resolution-1)*i+shiftAngle*total]) translate ([Radius*sqrt(1-(i/(resolution-1)*(i/(resolution-1)))),0,i*height/(resolution-1)]) sphere(r=baseRadius, center=true); rotate ([0,0,frequency*360/(resolution-1)*(i+1)+shiftAngle*total]) translate ([Radius*sqrt(1-((i+1)/(resolution-1)*((i+1)/(resolution-1)))),0,(i+1)*height/(resolution-1)]) sphere(r=baseRadius,center=true); } } } } } } //Alternate approach to spiral generation module spiral_alt (START_D = 10, SPACING = 5, THICKNESS = 2, H = 10, SPIRALS = 39) { $fn = 60; START_R = START_D / 2; union () { for (i = [0 : $fn]) { rotate ([0, 0, i * (360 / $fn)]) { for (x = [0: (SPIRALS - 1)]) { spiral_facet(i, x, START_R, SPACING, THICKNESS, H); } } } } } module spiral_facet (i, x, START_R, SPACING, W, H) { STEP_SIZE = ((SPACING + W) / $fn); STEP_OFFSET = i * STEP_SIZE; SPIRAL_START_OFFSET = (x * (SPACING + W)); ACTUAL_R = START_R + SPIRAL_START_OFFSET + STEP_OFFSET; L = 2 * (ACTUAL_R * tan((360 / $fn) / 2)); ANGLE = -atan( STEP_SIZE / (L / 2) ) / 2; OFFSET = START_R - (W / 2) + SPIRAL_START_OFFSET + STEP_OFFSET; translate ([OFFSET, 0, - H / 2]) { rotate ([0, 0, ANGLE]) { cube([W, L, H], center=true); //TODO: cutouts } } }