common/spiral.scad

150 lines
7.0 KiB
OpenSCAD

//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<spiral.scad>;
//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
}
}
}