gears

//make in https://openjscad.org/

function main(params)
{

var dist = (params.numTeeth*params.circularPitch/8.28) +(params.numTeeth2*params.circularPitch2/8.28);

// Main entry point; here we construct our solid:
var gear = Gear(params).translate([dist,dist,0]);
params.numTeeth = params.numTeeth2;
params.circularPitch = params.circularPitch2;
params.pressureAngle = params.pressureAngle2;
params.clearance = params.clearance2;
params.thickness = params.thickness2;
gear = union(gear,Gear(params));

return gear;
}

function Gear(params)
{
// Main entry point; here we construct our solid:
var gear = involuteGear(
params.numTeeth,
params.circularPitch,
params.pressureAngle,
params.clearance,
params.thickness
);
if(params.centerholeradius > 0)
{
var centerhole = CSG.cylinder({start: [0,0,-params.thickness], end: [0,0,params.thickness], radius: params.centerholeradius, resolution: 16});
gear = gear.subtract(centerhole);
}
return gear;
}

// Here we define the user editable parameters:
function getParameterDefinitions() {
return [
{ name: 'numTeeth', caption: 'Number of teeth:', type: 'int', default: 15 },
{ name: 'circularPitch', caption: 'Circular pitch:', type: 'float', default: 10 },
{ name: 'pressureAngle', caption: 'Pressure angle:', type: 'float', default: 20 },
{ name: 'clearance', caption: 'Clearance:', type: 'float', default: 0 },
{ name: 'thickness', caption: 'Thickness:', type: 'float', default: 5 },
{ name: 'centerholeradius', caption: 'Radius of center hole (0 for no hole):', type: 'float', default: 2 },

{ name: 'numTeeth2', caption: 'Number of teeth2:', type: 'int', default: 15 },{ name: 'circularPitch2', caption: 'Circular pitch2:', type: 'float', default: 10 },{ name: 'pressureAngle2', caption: 'Pressure angle2:', type: 'float', default: 20 },{ name: 'clearance2', caption: 'Clearance2:', type: 'float', default: 0 },{ name: 'thickness2', caption: 'Thickness2:', type: 'float', default: 5 },{ name: 'centerholeradius2', caption: 'Radius of center hole (0 for no hole):', type: 'float', default: 2 },

];
}

/*
For gear terminology see:
http://www.astronomiainumbria.org/advanced_internet_files/meccanica/easyweb.easynet.co.uk/_chrish/geardata.htm
Algorithm based on:
http://www.cartertools.com/involute.html

circularPitch: The distance between adjacent teeth measured at the pitch circle
*/
function involuteGear(numTeeth, circularPitch, pressureAngle, clearance, thickness)
{
// default values:
if(arguments.length < 3) pressureAngle = 20;
if(arguments.length < 4) clearance = 0;
if(arguments.length < 4) thickness = 1;

var addendum = circularPitch / Math.PI;
var dedendum = addendum + clearance;

// radiuses of the 4 circles:
var pitchRadius = numTeeth circularPitch / (2 Math.PI);
var baseRadius = pitchRadius Math.cos(Math.PI pressureAngle / 180);
var outerRadius = pitchRadius + addendum;
var rootRadius = pitchRadius - dedendum;

var maxtanlength = Math.sqrt(outerRadiusouterRadius - baseRadiusbaseRadius);
var maxangle = maxtanlength / baseRadius;

var tl_at_pitchcircle = Math.sqrt(pitchRadiuspitchRadius - baseRadiusbaseRadius);
var angle_at_pitchcircle = tl_at_pitchcircle / baseRadius;
var diffangle = angle_at_pitchcircle - Math.atan(angle_at_pitchcircle);
var angularToothWidthAtBase = Math.PI / numTeeth + 2*diffangle;

// build a single 2d tooth in the 'points' array:
var resolution = 5;
var points = [new CSG.Vector2D(0,0)];
for(var i = 0; i <= resolution; i++)
{
// first side of the tooth:
var angle = maxangle i / resolution;
var tanlength = angle
baseRadius;
var radvector = CSG.Vector2D.fromAngle(angle);
var tanvector = radvector.normal();
var p = radvector.times(baseRadius).plus(tanvector.times(tanlength));
points[i+1] = p;

// opposite side of the tooth:radvector = CSG.Vector2D.fromAngle(angularToothWidthAtBase - angle);    tanvector = radvector.normal().negated();p = radvector.times(baseRadius).plus(tanvector.times(tanlength));points[2 * resolution + 2 - i] = p;

}

// create the polygon and extrude into 3D:
var tooth3d = new CSG.Polygon2D(points).extrude({offset: [0, 0, thickness]});

var allteeth = new CSG();
for(var i = 0; i < numTeeth; i++)
{
var angle = i*360/numTeeth;
var rotatedtooth = tooth3d.rotateZ(angle);
allteeth = allteeth.unionForNonIntersecting(rotatedtooth);
}

// build the root circle:
points = [];
var toothAngle = 2 Math.PI / numTeeth;
var toothCenterAngle = 0.5
angularToothWidthAtBase;
for(var i = 0; i < numTeeth; i++)
{
var angle = toothCenterAngle + i * toothAngle;
var p = CSG.Vector2D.fromAngle(angle).times(rootRadius);
points.push(p);
}

// create the polygon and extrude into 3D:
var rootcircle = new CSG.Polygon2D(points).extrude({offset: [0, 0, thickness]});

var result = rootcircle.union(allteeth);

// center at origin:
//result = result.translate([0, 0, -thickness/2]);

return result;
}