946 lines
39 KiB
OpenSCAD
946 lines
39 KiB
OpenSCAD
|
// Algorithmic LEGO(r) Technic compatible gear generator
|
||
|
//
|
||
|
// NOTE regarding Patents: Since 1977 the LEGO Group has produced "Technic"
|
||
|
// elements with gear teeth, axles, axle-holes, and other features closely
|
||
|
// resembling the design(s) in this file, as part of their "Expert Builder"
|
||
|
// and "Technical Sets", now called "Technic" (see for example set 961,
|
||
|
// peeron.com/inv/sets/961-1?showpic=9288 ). By 1989 they had added pieces
|
||
|
// with rounded ends (see peeron.com/inv/sets/5264-1?showpic=8542 (set 5264
|
||
|
// from 1987) and peeron.com/inv/sets/5110-2?showpic=8543 (set 5110 from 1989))
|
||
|
// The object(s) produced by this SCAD file are different from real LEGO(r)
|
||
|
// elements, and any similarities of features, such as the shapes of axles
|
||
|
// and axle-holes, are functional in nature. The functions in question
|
||
|
// resemble those in LEGO patents that have already expired (or, if not
|
||
|
// patented, became prior art when the product(s) became available for
|
||
|
// purchase, i.e. 1989 at the latest). Nevertheless, one must not infringe
|
||
|
// on non-expired patents and any non-patent rights, such as LEGO(r)
|
||
|
// trademarks and brand identity. An example of such infringement would be
|
||
|
// to make objects and then try to "pass them off" as LEGO products. See
|
||
|
// for example the Kirkbi AG v. Ritvik Holdings Inc. case, (Supreme Court of
|
||
|
// Canada [2005] 3 S.C.R. 302).
|
||
|
//
|
||
|
// This was originally created by user bjepson on Thingiverse (thing 29989),
|
||
|
// then heavily modified and expanded by Robert Munafo:
|
||
|
// 20121226: separate parameters for rows/columns of cylinder holes and of
|
||
|
// "plus-shaped" holes
|
||
|
// * Rotate the holes by 20 degrees to take advantage of
|
||
|
// edge dithering both for improved hole width resolution
|
||
|
// and to provide a rough surface which better grips the
|
||
|
// smooth axles.
|
||
|
// * You can now get more than just a single row of plus-holes
|
||
|
// in each direction
|
||
|
//
|
||
|
// 20130105: added MCAD functions to make this file work all by itself (no
|
||
|
// need to hunt down missing pieces elsewhere)
|
||
|
// * More accurate axle hole dimensions
|
||
|
// * Round holes are actually round now (imagine that!)
|
||
|
// * Automatically determines correct parameters for number and placement
|
||
|
// of holes, based on number of teeth
|
||
|
//
|
||
|
// 20130106: fix small glitch seen at junction of fillet and bottom land (for
|
||
|
// illustration of the problem, see "0106-fix.jpg" at
|
||
|
// thingiverse.com/thing:40410)
|
||
|
|
||
|
// 32 teeth is the real "missing" gear size, because all the other
|
||
|
// multiples of 8 are available. An argument can also be made for 28 (which
|
||
|
// however is available in the new small turntable) or any other multiple of 4
|
||
|
// because the official gears are all multiples of 4, namely: 8, 12, 16,
|
||
|
// 20, 24, 28(turntable), 36, 40 and 56(big turntable).
|
||
|
//
|
||
|
// For my orrery designs ( see mrob.com/orrery ) I might use any integer
|
||
|
// number of teeth from 8 up to around 60 or 70.
|
||
|
//
|
||
|
// The holes parameters need to be chosen a certain way. To get a normal style
|
||
|
// gear with a + hole in the middle, the plus_row and plus_col should both
|
||
|
// be odd, and the holes_row, holes_col should both be even. To get a round
|
||
|
// hole in the center, do it the other way 'round. Then invoke it as
|
||
|
// myGearParamed(n_teeth, holes_row, holes_col, plus_row, plus_col)
|
||
|
//
|
||
|
// Examples:
|
||
|
// my 20 gear: holes_row=2, holes_col=2, plus_row=1, plus_col=1
|
||
|
// Standard 24 gear: holes_row=2, holes_col=2, plus_row=1, plus_col=1
|
||
|
// my 28 gear: holes_row=2, holes_col=2, plus_row=3, plus_col=1
|
||
|
// my 32 gear: holes_row=2, holes_col=2, plus_row=3, plus_col=3
|
||
|
// nonstandard 36 gear: holes_row=2, holes_col=2, plus_row=3, plus_col=3
|
||
|
// Standard 40 gear: holes_row=4, holes_col=2, plus_row=3, plus_col=3
|
||
|
// my 44 gear: holes_row=4, holes_col=2, plus_row=3, plus_col=3
|
||
|
// my 48 gear: holes_row=4, holes_col=4, plus_row=5, plus_col=3
|
||
|
//
|
||
|
// By default, the myGear function chooses the best values for all the holes paramters
|
||
|
// based on the number of teeth.
|
||
|
|
||
|
// Standard LEGO dimensions:
|
||
|
// Stud spacing = 8mm
|
||
|
// Hole diameter = 5mm
|
||
|
// Pin holes (on beams etc) have ending notches that are 0.8mm deep and 3mm in radius (i.e. diameter is 6mm)
|
||
|
// Axle mesh thickness = 1.85mm
|
||
|
// Thickness of all gear wheels is 3.8mm
|
||
|
// Standard 40t gear: root_radius=18.75 outer_radius=20.85 (mm_per_tooth =~ 3.1 by root)
|
||
|
// Standard 24t gear: root_radius=10.7 outer_radius=12.8 (mm_per_tooth =~ 3.06 by root)
|
||
|
// Standard 16t gear: root_radius=6.8 outer_radius=7.9 (mm_per_tooth =~ 3.05 by root)
|
||
|
// Standard 8t gear: root_radius=2.8 outer_radius=4.9 (mm_per_tooth =~ 3.05 by root)
|
||
|
|
||
|
// Gear radius:
|
||
|
//outer_radius = mm_per_tooth*(n_teeth/2+1)/3.1415926;
|
||
|
|
||
|
//-------------------------------------------
|
||
|
// Overview of this file
|
||
|
//-------------------------------------------
|
||
|
|
||
|
/* 32t planetary assembly */
|
||
|
|
||
|
/*rotate([0, 0, 10])
|
||
|
ring_gear_1u_32t();
|
||
|
satellites_32t();
|
||
|
translate([0, 0, -8])
|
||
|
color([0.5, 1, 1, 1])
|
||
|
carrier_32t_simpler();
|
||
|
translate([0, 0, 16])
|
||
|
rotate([0, 180, 0])
|
||
|
color([0.5, 1, 0.5, 1])
|
||
|
sun_drive_32t_simpler();*/
|
||
|
|
||
|
/* Standard 8-teeth gear */
|
||
|
|
||
|
//std_gear8();
|
||
|
|
||
|
/* Planetary ring gear with both inner and outer 40 teeth */
|
||
|
|
||
|
//planetary_ring_gear(1);
|
||
|
|
||
|
/* 40-teeth planetary ring gear with clutch */
|
||
|
|
||
|
//planetary_ring_gear_with_clutch();
|
||
|
|
||
|
/* Standard-16-teeth-like clutch gear */
|
||
|
|
||
|
//clutchGear(32);
|
||
|
|
||
|
/* Gear with clutch fully offset to one side */
|
||
|
|
||
|
//offsetClutchGear(16);
|
||
|
|
||
|
/* Gear with bearing only at one side */
|
||
|
|
||
|
//offsetGear(number_of_teeth=8, gear_height=3.8);
|
||
|
// Sample offset gear with 28 teeth and 4 holes
|
||
|
//gear28_4holes();
|
||
|
|
||
|
/* Gear with offset teeth, axle hole and sparse body */
|
||
|
|
||
|
//offsetGearSparse(20, gear_height=3.9);
|
||
|
|
||
|
/* Half-stud parametric gear with some holes */
|
||
|
|
||
|
myGear(32);
|
||
|
|
||
|
/* Generic gear with involute teeth */
|
||
|
|
||
|
//gear(mm_per_tooth=3.05, number_of_teeth=24, thickness=3.8, clearance=-0.1);
|
||
|
|
||
|
/* Same, but using an experimental OpenSCAD feature - vector concat() function */
|
||
|
|
||
|
//gear_concat(mm_per_tooth=3.05, number_of_teeth=24, thickness=3.8);
|
||
|
|
||
|
//-------------
|
||
|
|
||
|
module sun_drive_32t() {
|
||
|
root = 3.06*(32/2-1)/3.1415926;
|
||
|
segments = 32*2; // so gear teeth edge never match cylinder segment edges
|
||
|
difference() {
|
||
|
union() {
|
||
|
difference() {
|
||
|
translate([0, 0, 2]) gear_teeth(mm_per_tooth=3.06, number_of_teeth=32, thickness=4, clearance=-0.1);
|
||
|
cylinder($fn=100, h=8, r=root-0.5);
|
||
|
}
|
||
|
difference() {
|
||
|
translate([0, 0, 0.8]) cylinder($fn=32*2, h=7.2, r=root);
|
||
|
translate([0, 0, -0.1]) cylinder($fn=32*2, h=7.3, r=root-1);
|
||
|
translate([0, 0, 7.2-0.1]) cylinder($fn=32*2, h=1, r=3.06*(24/2)/3.1415926);
|
||
|
}
|
||
|
translate([0, 0, 3.5]) cylinder($fn=32*2, h=1, r=root-0.5);
|
||
|
cylinder($fn=100, h=8, r=3.5);
|
||
|
difference() {
|
||
|
union() {
|
||
|
translate([-8, 0, 0]) cylinder($fn=32*2, h=8, r=3.5);
|
||
|
translate([0, -8, 0]) cylinder($fn=32*2, h=8, r=3.5);
|
||
|
translate([0, 8, 0]) cylinder($fn=32*2, h=8, r=3.5);
|
||
|
translate([8, 0, 0]) cylinder($fn=32*2, h=8, r=3.5);
|
||
|
translate([-0.5, -root+0.5, 0]) cube(size=[1, root*2-1, 8]);
|
||
|
rotate([0, 0, 90]) translate([-0.5, -root+0.5, 0]) cube(size=[1, root*2-1, 8]);
|
||
|
}
|
||
|
translate([-20, -20, 8-0.8]) cube(size=[40, 40, 1]);
|
||
|
translate([-20, -20, -0.2]) cube(size=[40, 40, 1]);
|
||
|
}
|
||
|
}
|
||
|
translate([-8, 0, -0.2]) cylinder($fn=32*2, h=10, r=2.4);
|
||
|
translate([0, -8, -0.2]) cylinder($fn=32*2, h=10, r=2.4);
|
||
|
translate([0, 8, -0.2]) cylinder($fn=32*2, h=10, r=2.4);
|
||
|
translate([8, 0, -0.2]) cylinder($fn=32*2, h=10, r=2.4);
|
||
|
rotate([0, 0, 45]) axleCut(0, 0, -0.2, 10);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module sun_drive_32t_no_holes() {
|
||
|
root = 3.06*(32/2-1)/3.1415926;
|
||
|
segments = 32*2; // so gear teeth edge never match cylinder segment edges
|
||
|
union() {
|
||
|
difference() {
|
||
|
union() {
|
||
|
difference() {
|
||
|
translate([0, 0, 2]) gear_teeth(mm_per_tooth=3.06, number_of_teeth=32, thickness=4, clearance=-0.1);
|
||
|
cylinder($fn=100, h=8, r=root-0.5);
|
||
|
}
|
||
|
difference() {
|
||
|
translate([0, 0, 0.8]) cylinder($fn=32*2, h=7.2, r=root);
|
||
|
translate([0, 0, -0.1]) cylinder($fn=32*2, h=7.1, r=root-1);
|
||
|
translate([0, 0, 7-0.1]) cylinder($fn=32*2, h=1.2, r=3.06*(24/2)/3.1415926);
|
||
|
}
|
||
|
cylinder($fn=100, h=8, r=3.5);
|
||
|
union() {
|
||
|
translate([-0.5, -root+0.5, 0.8]) cube(size=[1, root*2-1, 6.4]);
|
||
|
rotate([0, 0, 90]) translate([-0.5, -root+0.5, 0.8]) cube(size=[1, root*2-1, 6.4]);
|
||
|
}
|
||
|
translate([0, 0, 3.5]) cylinder($fn=32*2, h=1, r=root-0.5);
|
||
|
}
|
||
|
rotate([0, 0, 45]) axleCut(0, 0, -0.2, 10);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module sun_drive_32t_simpler() {
|
||
|
root = 3.06*(32/2-1)/3.1415926;
|
||
|
segments = 32*2; // so gear teeth edge never match cylinder segment edges
|
||
|
union() {
|
||
|
difference() {
|
||
|
union() {
|
||
|
difference() {
|
||
|
translate([0, 0, 2]) gear_teeth(mm_per_tooth=3.06, number_of_teeth=32, thickness=4, clearance=-0.1);
|
||
|
cylinder($fn=100, h=8, r=root-0.5);
|
||
|
}
|
||
|
difference() {
|
||
|
translate([0, 0, 0.8]) cylinder($fn=32*2, h=7.2, r=root);
|
||
|
translate([0, 0, -0.1]) cylinder($fn=32*2, h=7.1, r=root-1);
|
||
|
}
|
||
|
cylinder($fn=100, h=8, r=3.5);
|
||
|
union() {
|
||
|
translate([-0.5, -root+0.5, 0.8]) cube(size=[1, root*2-1, 6.4]);
|
||
|
rotate([0, 0, 90]) translate([-0.5, -root+0.5, 0.8]) cube(size=[1, root*2-1, 6.4]);
|
||
|
}
|
||
|
}
|
||
|
rotate([0, 0, 45]) axleCut(0, 0, -0.2, 10);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Simpler planetary carrier
|
||
|
module carrier_32t_simpler() {
|
||
|
root = 3.06*(32/2-1)/3.1415926;
|
||
|
segments = 32*2; // so gear teeth edge never match cylinder segment edges
|
||
|
difference() {
|
||
|
union() {
|
||
|
difference() {
|
||
|
translate([0, 0, 2]) gear_teeth(mm_per_tooth=3.06, number_of_teeth=32, thickness=4, clearance=-0.1);
|
||
|
cylinder($fn=100, h=8, r=root-0.5);
|
||
|
}
|
||
|
difference() {
|
||
|
translate([0, 0, 0.8]) cylinder($fn=32*2, h=7.2, r=root);
|
||
|
translate([0, 0, -0.1]) cylinder($fn=32*2, h=7.1, r=root-1);
|
||
|
}
|
||
|
cylinder($fn=100, h=8, r=3.5);
|
||
|
difference() {
|
||
|
union() {
|
||
|
translate([-8, 0, 0.1]) cylinder($fn=32*2, h=8-0.2, r=3.5);
|
||
|
translate([0, -8, 0.1]) cylinder($fn=32*2, h=8-0.2, r=3.5);
|
||
|
translate([0, 8, 0.1]) cylinder($fn=32*2, h=8-0.2, r=3.5);
|
||
|
translate([8, 0, 0.1]) cylinder($fn=32*2, h=8-0.2, r=3.5);
|
||
|
translate([-0.5, -root+0.5, 0]) cube(size=[1, root*2-1, 8]);
|
||
|
rotate([0, 0, 90]) translate([-0.5, -root+0.5, 0]) cube(size=[1, root*2-1, 8]);
|
||
|
}
|
||
|
translate([-20, -20, 8-0.8]) cube(size=[40, 40, 1]);
|
||
|
translate([-20, -20, -0.2]) cube(size=[40, 40, 1]);
|
||
|
}
|
||
|
}
|
||
|
translate([0, 0, -0.2]) cylinder($fn=32, h=10, r=2.4);
|
||
|
|
||
|
translate([-8, 0, -0.2]) cylinder($fn=32, h=10, r=2.4);
|
||
|
translate([0, -8, -0.2]) cylinder($fn=32, h=10, r=2.4);
|
||
|
translate([0, 8, -0.2]) cylinder($fn=32, h=10, r=2.4);
|
||
|
translate([8, 0, -0.2]) cylinder($fn=32, h=10, r=2.4);
|
||
|
|
||
|
translate([-8, 0, 7.2]) cylinder($fn=32, h=0.8+0.1, r=2.9);
|
||
|
translate([0, -8, 7.2]) cylinder($fn=32, h=0.8+0.1, r=2.9);
|
||
|
translate([0, 8, 7.2]) cylinder($fn=32, h=0.8+0.1, r=2.9);
|
||
|
translate([8, 0, 7.2]) cylinder($fn=32, h=0.8+0.1, r=2.9);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module carrier_32t() {
|
||
|
root = 3.06*(32/2-1)/3.1415926;
|
||
|
segments = 32*2; // so gear teeth edge never match cylinder segment edges
|
||
|
difference() {
|
||
|
union() {
|
||
|
difference() {
|
||
|
translate([0, 0, 2]) gear_teeth(mm_per_tooth=3.06, number_of_teeth=32, thickness=4, clearance=-0.1);
|
||
|
cylinder($fn=100, h=8, r=root-0.5);
|
||
|
}
|
||
|
difference() {
|
||
|
translate([0, 0, 0.8]) cylinder($fn=32*2, h=7.2, r=root);
|
||
|
translate([0, 0, -0.1]) cylinder($fn=32*2, h=7.3, r=root-1);
|
||
|
translate([0, 0, 7.2-0.1]) cylinder($fn=32*2, h=1, r=3.06*(24/2)/3.1415926);
|
||
|
}
|
||
|
translate([0, 0, 3.5]) cylinder($fn=32*2, h=1, r=root-0.5);
|
||
|
cylinder($fn=100, h=8, r=3.5);
|
||
|
difference() {
|
||
|
union() {
|
||
|
translate([-8, 0, 0]) cylinder($fn=32*2, h=8, r=3.5);
|
||
|
translate([0, -8, 0]) cylinder($fn=32*2, h=8, r=3.5);
|
||
|
translate([0, 8, 0]) cylinder($fn=32*2, h=8, r=3.5);
|
||
|
translate([8, 0, 0]) cylinder($fn=32*2, h=8, r=3.5);
|
||
|
translate([-0.5, -root+0.5, 0]) cube(size=[1, root*2-1, 8]);
|
||
|
rotate([0, 0, 90]) translate([-0.5, -root+0.5, 0]) cube(size=[1, root*2-1, 8]);
|
||
|
}
|
||
|
translate([-20, -20, 8-0.8]) cube(size=[40, 40, 1]);
|
||
|
translate([-20, -20, -0.2]) cube(size=[40, 40, 1]);
|
||
|
}
|
||
|
}
|
||
|
translate([-8, 0, -0.2]) cylinder($fn=32*2, h=10, r=2.4);
|
||
|
translate([0, -8, -0.2]) cylinder($fn=32*2, h=10, r=2.4);
|
||
|
translate([0, 0, -0.2]) cylinder($fn=32*2, h=10, r=2.4);
|
||
|
translate([0, 8, -0.2]) cylinder($fn=32*2, h=10, r=2.4);
|
||
|
translate([8, 0, -0.2]) cylinder($fn=32*2, h=10, r=2.4);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Most compact planetary ring gear: 1 unit thick, 32 teeth outside, 24 teeth inside
|
||
|
// + 3 notches at each side to lower friction
|
||
|
module ring_gear_1u_32t() {
|
||
|
difference() {
|
||
|
union() {
|
||
|
translate([0, 0, 2]) gear(mm_per_tooth=3.06, number_of_teeth=32, thickness=4, clearance=-0.1);
|
||
|
translate([0, 0, 0.8]) cylinder($fn=100, h=6.4, r=3.06*(32/2-1)/3.1415926);
|
||
|
// notches, top
|
||
|
translate([-12.8, 0, 6]) difference() {
|
||
|
sphere($fn=30, r=2, center=true);
|
||
|
translate([0, 0, -0.9]) cube(size=[6, 6, 4], center=true);
|
||
|
}
|
||
|
rotate([0, 0, 120]) translate([-12.8, 0, 6]) difference() {
|
||
|
sphere($fn=30, r=2, center=true);
|
||
|
translate([0, 0, -0.9]) cube(size=[6, 6, 4], center=true);
|
||
|
}
|
||
|
rotate([0, 0, 240]) translate([-12.8, 0, 6]) difference() {
|
||
|
sphere($fn=30, r=2, center=true);
|
||
|
translate([0, 0, -0.9]) cube(size=[6, 6, 4], center=true);
|
||
|
}
|
||
|
// notches, bottom
|
||
|
translate([-12.8, 0, 2]) difference() {
|
||
|
sphere($fn=30, r=2, center=true);
|
||
|
translate([0, 0, 0.9]) cube(size=[6, 6, 4], center=true);
|
||
|
}
|
||
|
rotate([0, 0, 120]) translate([-12.8, 0, 2]) difference() {
|
||
|
sphere($fn=30, r=2, center=true);
|
||
|
translate([0, 0, 0.9]) cube(size=[6, 6, 4], center=true);
|
||
|
}
|
||
|
rotate([0, 0, 240]) translate([-12.8, 0, 2]) difference() {
|
||
|
sphere($fn=30, r=2, center=true);
|
||
|
translate([0, 0, 0.9]) cube(size=[6, 6, 4], center=true);
|
||
|
}
|
||
|
}
|
||
|
translate([0, 0, 1.8]) gear(mm_per_tooth=3.1415926, number_of_teeth=24, thickness=4.4, clearance=-0.1);
|
||
|
translate([0, 0, -0.1]) cylinder($fn=100, h=8.2, r=(24/2-1));
|
||
|
// translate([0, 0, -0.1]) cylinder($fn=100, h=2.1, r=(24/2-1));
|
||
|
// translate([0, 0, 6]) cylinder($fn=100, h=2.1, r=(24/2-1));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Satellites and sun gear for 32t ring gear
|
||
|
module satellites_32t() {
|
||
|
color([1, 0.5, 0.5, 1]) rotate([0, 0, -5]) std_gear8();
|
||
|
color([0.5, 0.5, 1, 1]) translate([8, 0, 0]) rotate([0, 0, 30]) std_gear8();
|
||
|
color([0.5, 0.5, 1, 1]) translate([-8, 0, 0]) rotate([0, 0, 30]) std_gear8();
|
||
|
color([0.5, 0.5, 1, 1]) translate([0, 8, 0]) rotate([0, 0, 30]) std_gear8();
|
||
|
color([0.5, 0.5, 1, 1]) translate([0, -8, 0]) rotate([0, 0, 30]) std_gear8();
|
||
|
}
|
||
|
|
||
|
//-------------
|
||
|
|
||
|
// Standard 8-teeth gear
|
||
|
module std_gear8() {
|
||
|
difference() {
|
||
|
union() {
|
||
|
cylinder($fn=50, h=8, r=3.05*(8/2-1)/3.1415926);
|
||
|
translate([0, 0, 2.1]) gear(mm_per_tooth=3.05, number_of_teeth=8, thickness=3.8, clearance=-0.1);
|
||
|
}
|
||
|
axle(0, 0, -1, 10);
|
||
|
}}
|
||
|
|
||
|
module planetary_ring_gear_with_clutch() {
|
||
|
union() {
|
||
|
difference() {
|
||
|
cylinder($fn=100, h=8, r=22);
|
||
|
// make inner gear slightly bigger
|
||
|
translate([0, 0, -0.1]) gear(mm_per_tooth=3.1415926, number_of_teeth=40, thickness=6.1);
|
||
|
cylinder($fn=100, h=8.1, r=19);
|
||
|
}
|
||
|
translate([0, 0, 8])
|
||
|
difference() {
|
||
|
union() {
|
||
|
cylinder($fn=100, h=2, r=(0.1+3.1*(40/2+1)/3.1415926));
|
||
|
translate([0, 0, 2]) gear(mm_per_tooth=3.1, number_of_teeth=40, thickness=4, clearance=-0.1);
|
||
|
translate([0, 0, 5]) cylinder($fn=100, h=2.2, r=(3.1*(40/2-1)/3.1415926));
|
||
|
cylinder($fn=100, h=8, r=6.8);
|
||
|
}
|
||
|
translate([0, 0, 4]) difference() {
|
||
|
translate([0, 0, -0.1]) cylinder($fn=100, h=20, r=5.8);
|
||
|
translate([0, 0, -0.1]) cylinder($fn=100, h=20.2, r=3.5);
|
||
|
}
|
||
|
translate([0, 0, -0.1]) difference() {
|
||
|
cylinder($fn=100, h=8.2, r=(3.1*(40/2-1)/3.1415926)-1);
|
||
|
translate([0, 0, 3.5]) cylinder($fn=100, h=1, r=(3.1*(40/2-1)/3.1415926)-1);
|
||
|
translate([0, 0, -0.1]) cylinder($fn=100, h=10, r=6.8);
|
||
|
translate([-0.5, -20, -0.1]) cube(size=[1, 40, 10]);
|
||
|
translate([-20, -0.5, -0.1]) cube(size=[40, 1, 10]);
|
||
|
/* translate([-10, 8-0.5, -0.1]) cube(size=[20, 1, 10]);
|
||
|
translate([-10, -8-0.5, -0.1]) cube(size=[20, 1, 10]);
|
||
|
translate([8-0.5, -10, -0.1]) cube(size=[1, 20, 10]);
|
||
|
translate([-8-0.5, -10, -0.1]) cube(size=[1, 20, 10]);
|
||
|
rotate([0, 0, -45]) translate([-0.5, 10, -0.1]) cube(size=[1, 10, 10]);
|
||
|
rotate([0, 0, 45]) translate([-0.5, 10, -0.1]) cube(size=[1, 10, 10]);
|
||
|
rotate([0, 0, -135]) translate([-0.5, 10, -0.1]) cube(size=[1, 10, 10]);
|
||
|
rotate([0, 0, 135]) translate([-0.5, 10, -0.1]) cube(size=[1, 10, 10]);*/
|
||
|
}
|
||
|
translate([0, 0, -0.1]) cylinder($fn=100, h=10, r=2.4);
|
||
|
}
|
||
|
translate([0, 0, 10.2]) union() {
|
||
|
clutchTeeth();
|
||
|
rotate([0, 0, 90]) clutchTeeth();
|
||
|
rotate([0, 0, 180]) clutchTeeth();
|
||
|
rotate([0, 0, -90]) clutchTeeth();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Planetary ring gear, 2 stud thick, sparse
|
||
|
module planetary_ring_gear(plane_height = 1) {
|
||
|
union() {
|
||
|
difference() {
|
||
|
translate([0, 0, 2]) cylinder($fn=80, h=6, r=22);
|
||
|
// make inner gear slightly bigger
|
||
|
translate([0, 0, -0.1]) gear_teeth(mm_per_tooth=3.1415926, number_of_teeth=40, thickness=6.1);
|
||
|
cylinder($fn=80, h=8.1, r=19);
|
||
|
}
|
||
|
translate([0, 0, 7.9])
|
||
|
difference() {
|
||
|
union() {
|
||
|
cylinder($fn=80, h=2, r=(0.1+3.1*(40/2+1)/3.1415926));
|
||
|
translate([0, 0, 2]) gear(mm_per_tooth=3.1, number_of_teeth=40, thickness=4, clearance=-0.1);
|
||
|
translate([0, 0, 5]) cylinder($fn=80, h=2.2, r=(3.1*(40/2-1)/3.1415926));
|
||
|
cylinder($fn=50, h=8, r=3.5);
|
||
|
}
|
||
|
difference() {
|
||
|
translate([0, 0, -0.1]) cylinder($fn=80, h=0.9, r=(3.1*(40/2-1)/3.1415926)-1);
|
||
|
translate([0, 0, -0.2]) cylinder($fn=50, h=1, r=3.5);
|
||
|
}
|
||
|
translate([0, 0, plane_height+0.8-0.1]) difference() {
|
||
|
cylinder($fn=80, h=8.2-plane_height-0.8, r=(3.1*(40/2-1)/3.1415926)-1);
|
||
|
|
||
|
translate([-0.5, -20, -0.1]) cube(size=[1, 40, 10]);
|
||
|
translate([-20, -0.5, -0.1]) cube(size=[40, 1, 10]);
|
||
|
translate([-10, 8-0.5, -0.1]) cube(size=[20, 1, 10]);
|
||
|
translate([-10, -8-0.5, -0.1]) cube(size=[20, 1, 10]);
|
||
|
translate([8-0.5, -10, -0.1]) cube(size=[1, 20, 10]);
|
||
|
translate([-8-0.5, -10, -0.1]) cube(size=[1, 20, 10]);
|
||
|
rotate([0, 0, -45]) translate([-0.5, 10, -0.1]) cube(size=[1, 10, 10]);
|
||
|
rotate([0, 0, 45]) translate([-0.5, 10, -0.1]) cube(size=[1, 10, 10]);
|
||
|
rotate([0, 0, -135]) translate([-0.5, 10, -0.1]) cube(size=[1, 10, 10]);
|
||
|
rotate([0, 0, 135]) translate([-0.5, 10, -0.1]) cube(size=[1, 10, 10]);
|
||
|
|
||
|
translate([0, 0, -0.1]) cylinder($fn=40, h=10, r=3.5);
|
||
|
translate([-8, -8, -0.1]) cylinder($fn=40, h=10, r=3.5);
|
||
|
translate([-8, 0, -0.1]) cylinder($fn=40, h=10, r=3.5);
|
||
|
translate([-8, 8, -0.1]) cylinder($fn=40, h=10, r=3.5);
|
||
|
translate([0, -8, -0.1]) cylinder($fn=40, h=10, r=3.5);
|
||
|
translate([0, 8, -0.1]) cylinder($fn=40, h=10, r=3.5);
|
||
|
translate([8, -8, -0.1]) cylinder($fn=40, h=10, r=3.5);
|
||
|
translate([8, 0, -0.1]) cylinder($fn=40, h=10, r=3.5);
|
||
|
translate([8, 8, -0.1]) cylinder($fn=40, h=10, r=3.5);
|
||
|
}
|
||
|
translate([-8, -8, -0.1]) cylinder($fn=40, h=10, r=2.4);
|
||
|
translate([-8, 0, -0.1]) cylinder($fn=40, h=10, r=2.4);
|
||
|
translate([-8, 8, -0.1]) cylinder($fn=40, h=10, r=2.4);
|
||
|
translate([0, -8, -0.1]) cylinder($fn=40, h=10, r=2.4);
|
||
|
translate([0, 0, -0.1]) cylinder($fn=40, h=10, r=2.4);
|
||
|
translate([0, 8, -0.1]) cylinder($fn=40, h=10, r=2.4);
|
||
|
translate([8, -8, -0.1]) cylinder($fn=40, h=10, r=2.4);
|
||
|
translate([8, 0, -0.1]) cylinder($fn=40, h=10, r=2.4);
|
||
|
translate([8, 8, -0.1]) cylinder($fn=40, h=10, r=2.4);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Example 28-teeth offset gear with 4 pin holes
|
||
|
module gear28_4holes() {
|
||
|
difference() {
|
||
|
offsetGear(28, 3.9);
|
||
|
translate([-8, 0, 0]) pinHole(3.9);
|
||
|
translate([0, 8, 0]) pinHole(3.9);
|
||
|
translate([8, 0, 0]) pinHole(3.9);
|
||
|
translate([0, -8, 0]) pinHole(3.9);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Hole for a standard LEGO pin with height parameter intended to be cut
|
||
|
// from some solid part (like half or full beam)
|
||
|
module pinHole(height=8) {
|
||
|
union() {
|
||
|
translate([0, 0, -0.1]) cylinder($fs=0.5, h=height+0.2, r=2.4);
|
||
|
translate([0, 0, -0.1]) cylinder($fs=0.5, h=0.8+0.1, r=2.9);
|
||
|
translate([0, 0, height-0.8]) cylinder($fs=0.5, h=0.8+0.1, r=2.9);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Gear with offset teeth, axle hole and sparse body
|
||
|
module offsetGearSparse(number_of_teeth, gear_height=3.9) {
|
||
|
root_radius = 3.05*number_of_teeth/3.1415926/2 - 3.05/3.1415926;
|
||
|
difference() {
|
||
|
offsetGear(number_of_teeth, gear_height);
|
||
|
translate([0, 0, -0.1])
|
||
|
difference() {
|
||
|
cylinder($fn=50, h=gear_height+0.2, r=root_radius-1.5);
|
||
|
cylinder($fn=50, h=gear_height+0.2, r=3.5);
|
||
|
translate([-root_radius-1, 1.5, 0]) cube(size=[root_radius*2+2, 2, 2*gear_height+0.4], center=false);
|
||
|
translate([-root_radius-1, -3.5, 0]) cube(size=[root_radius*2+2, 2, 2*gear_height+0.4], center=false);
|
||
|
rotate([0, 0, 90]) {
|
||
|
translate([-root_radius-1, 1.5, 0]) cube(size=[root_radius*2+2, 2, 2*gear_height+0.4], center=false);
|
||
|
translate([-root_radius-1, -3.5, 0]) cube(size=[root_radius*2+2, 2, 2*gear_height+0.4], center=false);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Gear with offset teeth and axle hole
|
||
|
module offsetGear(number_of_teeth, gear_height=3.9) {
|
||
|
difference() {
|
||
|
union() {
|
||
|
gear(number_of_teeth=number_of_teeth, mm_per_tooth=3.05, thickness=gear_height, clearance=-0.1);
|
||
|
translate([0, 0, gear_height]) cylinder($fs=0.5, h=8-gear_height, r=3.5);
|
||
|
}
|
||
|
// axle hole
|
||
|
axle(0, 0, -1, 10);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Gear with interface for driving ring, with offset teeth
|
||
|
// => The minimal printable size of such gear is 9 teeth...
|
||
|
// (8 teeth will probably be too thin in some places)
|
||
|
module offsetClutchGear(number_of_teeth) {
|
||
|
union() {
|
||
|
difference() {
|
||
|
union() {
|
||
|
gear(number_of_teeth=number_of_teeth, mm_per_tooth=3.05, thickness=3.9);
|
||
|
translate([0, 0, 3.9]) cylinder($fn=100, h=4.1, r=6.8);
|
||
|
}
|
||
|
difference() {
|
||
|
translate([0, 0, 4.8]) cylinder($fn=100, h=4, r=5.8);
|
||
|
translate([0, 0, 4.8]) cylinder($fn=100, h=4, r=3.3);
|
||
|
}
|
||
|
// round hole
|
||
|
translate([0, 0, -3]) cylinder($fn=100, h=12, r=2.45);
|
||
|
// axle hole
|
||
|
//axle(0, 0, -1, 10);
|
||
|
}
|
||
|
translate([0, 0, 3]) union() {
|
||
|
clutchTeeth();
|
||
|
rotate([0, 0, 90]) clutchTeeth();
|
||
|
rotate([0, 0, 180]) clutchTeeth();
|
||
|
rotate([0, 0, -90]) clutchTeeth();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Axle
|
||
|
module axle(x, y, z, height) {
|
||
|
axle_gap = 1.85;
|
||
|
hole_radius = 2.4;
|
||
|
union() {
|
||
|
translate([x - hole_radius, y - axle_gap/2, z])
|
||
|
roundedRect([hole_radius * 2, axle_gap, height], .2);
|
||
|
translate([x - axle_gap/2, y - hole_radius, z])
|
||
|
roundedRect([axle_gap, hole_radius * 2, height], .2);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Axle hole (for difference()) with fixing slit
|
||
|
module axleCut(x, y, z, height) {
|
||
|
axle_gap = 1.85;
|
||
|
axle_gap_cut = 1.7;
|
||
|
hole_radius = 2.4;
|
||
|
union() {
|
||
|
translate([x - hole_radius, y - axle_gap/2, z])
|
||
|
roundedRect([hole_radius * 2, axle_gap, height], .2);
|
||
|
translate([x - axle_gap_cut/2, y - hole_radius, z])
|
||
|
roundedRect([axle_gap_cut, hole_radius * 2, height], .2);
|
||
|
translate([x-0.25, y-5, z]) cube(size=[0.5, 10, height]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Gear with interface for driving ring, with centered teeth
|
||
|
// => The minimal size of such gear is 16 teeth
|
||
|
module clutchGear(number_of_teeth) {
|
||
|
union() {
|
||
|
difference() {
|
||
|
union() {
|
||
|
gear(thickness=3.7, mm_per_tooth=3.05, number_of_teeth=number_of_teeth, clearance = -0.1);
|
||
|
cylinder($fn=100, h=5.8, r=6.8);
|
||
|
translate([0, 0, -2]) cylinder($fn=100, h=3, r=3.7);
|
||
|
}
|
||
|
difference() {
|
||
|
translate([0, 0, 1.8]) cylinder($fn=100, h=4.1, r=5.8);
|
||
|
translate([0, 0, 1.8]) cylinder($fn=100, h=4.1, r=3.3);
|
||
|
}
|
||
|
translate([0, 0, -3]) cylinder($fn=100, h=10, r=2.5);
|
||
|
translate([0, 0, -2.2]) cylinder($fn=100, h=1, r=3.1);
|
||
|
}
|
||
|
clutchTeeth();
|
||
|
rotate([0, 0, 90]) clutchTeeth();
|
||
|
rotate([0, 0, 180]) clutchTeeth();
|
||
|
rotate([0, 0, -90]) clutchTeeth();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Clutch: 0.7 from the top, 1.5 width, 1 thickness
|
||
|
module clutchTeeth() {
|
||
|
polyhedron(points=[
|
||
|
[5.8, -0.8, 1.8], // 5.8+0.1, 1.8-0.1, чтобы утопить
|
||
|
[5.8, 0.8, 1.8],
|
||
|
[4.8, -0.8, 1.8],
|
||
|
[4.8, 0.8, 1.8],
|
||
|
[5.8, 0, 5],
|
||
|
[4.8, 0, 5],
|
||
|
], triangles=[
|
||
|
[0, 1, 2],
|
||
|
[2, 1, 3],
|
||
|
[0, 4, 1],
|
||
|
[0, 2, 4],
|
||
|
[4, 2, 5],
|
||
|
[3, 1, 4],
|
||
|
[4, 5, 3],
|
||
|
[2, 3, 5],
|
||
|
]);
|
||
|
}
|
||
|
|
||
|
module myGear(n_teeth) {
|
||
|
if (n_teeth >= 56) {
|
||
|
myGearParamed(n_teeth, 6, 4, 5, 5);
|
||
|
} else if (n_teeth >= 48) {
|
||
|
myGearParamed(n_teeth, 4, 4, 5, 3);
|
||
|
} else if (n_teeth >= 40) {
|
||
|
myGearParamed(n_teeth, 4, 2, 3, 3);
|
||
|
} else if (n_teeth >= 32) {
|
||
|
myGearParamed(n_teeth, 2, 2, 3, 3);
|
||
|
} else if (n_teeth >= 26) {
|
||
|
myGearParamed(n_teeth, 2, 2, 3, 1);
|
||
|
} else if (n_teeth >= 21) {
|
||
|
myGearParamed(n_teeth, 2, 2, 1, 1);
|
||
|
} else {
|
||
|
myGearParamed(n_teeth, 0, 0, 1, 1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module myGearParamed(num_teeth, holes_row, holes_col, plus_row, plus_col)
|
||
|
{
|
||
|
jaggy_angle = 0;
|
||
|
beam_width = 7.8; // Needs to be a bit less than the LEGO stud spacing = 7.99 mm
|
||
|
gearHeight = 3.67;
|
||
|
|
||
|
axle_gap = 1.9; // axle thickness is actually about 1.8 mm
|
||
|
hole_radius = 2.5;
|
||
|
|
||
|
difference() {
|
||
|
gear(thickness=gearHeight, number_of_teeth=num_teeth, mm_per_tooth=3.1415926);
|
||
|
|
||
|
// We do two rectangular grids of holes, rotate 90 degrees and do them
|
||
|
// again.
|
||
|
for (i = [jaggy_angle, jaggy_angle+90]) {
|
||
|
rotate([0,0,i]) {
|
||
|
// Cut the cross-axle holes (8.0mm = stud spacing)
|
||
|
if (plus_row > 0) {
|
||
|
for (x=[-4 * (plus_row - 1 ): 8.0 : 4 * (plus_row -1 )]) {
|
||
|
for (y=[-4 * (plus_col - 1 ): 8.0 : 4 * (plus_col -1)]) {
|
||
|
translate([x - hole_radius, y - axle_gap/2, -0.1])
|
||
|
roundedRect([hole_radius * 2, axle_gap, gearHeight+0.2], .2);
|
||
|
translate([x - axle_gap/2, y - hole_radius, -0.1])
|
||
|
roundedRect([axle_gap, hole_radius * 2, gearHeight+0.2], .2);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (holes_row > 0) {
|
||
|
// Cut the round holes
|
||
|
for (x=[-4 * (holes_row-1) : 8.0 : 4 * (holes_row-1)]) {
|
||
|
for (y=[-4 * (holes_col-1) : 8.0 : 4 * (holes_col-1)]) {
|
||
|
translate([x, y, -0.1]) {
|
||
|
cylinder(r=hole_radius, h = gearHeight+0.2, $fs=0.5);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// ---------------------------------------------------------------------------------
|
||
|
//
|
||
|
// module for rounded rectangles by tlrobinson on Thingiverse in a
|
||
|
// comment posted to http://www.thingiverse.com/thing:9347 on March
|
||
|
// 29, 2012, 3:57:46 AM EDT
|
||
|
//
|
||
|
module roundedRect(size, radius) {
|
||
|
x = size[0];
|
||
|
y = size[1];
|
||
|
z = size[2];
|
||
|
|
||
|
linear_extrude(height=z)
|
||
|
hull() {
|
||
|
translate([radius, radius, 0])
|
||
|
circle(r=radius);
|
||
|
|
||
|
translate([x - radius, radius, 0])
|
||
|
circle(r=radius);
|
||
|
|
||
|
translate([x - radius, y - radius, 0])
|
||
|
circle(r=radius);
|
||
|
|
||
|
translate([radius, y - radius, 0])
|
||
|
circle(r=radius);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////
|
||
|
|
||
|
|
||
|
// Good gear() module -- without experimental OpenSCAD features
|
||
|
// Does not support hole_diameter and teeth_to_hide parameters,
|
||
|
// but generates good solid gears with no face problems
|
||
|
module gear(
|
||
|
mm_per_tooth = 3, //this is the "circular pitch", the circumference of the pitch circle divided by the number of teeth
|
||
|
number_of_teeth = 11, //total number of teeth around the entire perimeter
|
||
|
thickness = 6, //thickness of gear in mm
|
||
|
twist = 0, //teeth rotate this many degrees from bottom of gear to top. 360 makes the gear a screw with each thread going around once
|
||
|
pressure_angle = 28, //Controls how straight or bulged the tooth sides are. In degrees.
|
||
|
clearance = 0.0, //gap between top of a tooth on one gear and bottom of valley on a meshing gear (in millimeters)
|
||
|
backlash = 0.0 //gap between two meshing teeth, in the direction along the circumference of the pitch circle
|
||
|
) {
|
||
|
assign(pi = 3.1415926)
|
||
|
assign(p = mm_per_tooth * number_of_teeth / pi / 2) //radius of pitch circle
|
||
|
assign(c = p + mm_per_tooth / pi - clearance) //radius of outer circle
|
||
|
assign(b = p*cos(pressure_angle)) //radius of base circle
|
||
|
assign(r = p-(c-p)-clearance) //radius of root circle
|
||
|
assign(t = mm_per_tooth/2-backlash/2) //tooth thickness at pitch circle
|
||
|
assign(k = -iang(b, p) - t/2/p/pi*180) //angle to where involute meets base circle on each side of tooth
|
||
|
difference() {
|
||
|
union() {
|
||
|
// $fn: so gear teeth edge never match cylinder segment edges
|
||
|
translate([0, 0, -1]) cylinder($fn=number_of_teeth*2, h=thickness+2, r=r);
|
||
|
translate([0, 0, -0.5])
|
||
|
for (i = [0:number_of_teeth-1])
|
||
|
rotate([0,0,i*360/number_of_teeth])
|
||
|
linear_extrude(height = thickness+1, center = false, convexity = 10, twist = twist)
|
||
|
polygon(
|
||
|
points=[
|
||
|
[0, 0],
|
||
|
polar(r, -181/number_of_teeth),
|
||
|
polar(r*0.9, r<b ? k : -180/number_of_teeth),
|
||
|
q7(0/5,r,b,c,k,1),
|
||
|
q7(1/5,r,b,c,k,1),
|
||
|
q7(2/5,r,b,c,k,1),
|
||
|
q7(3/5,r,b,c,k,1),
|
||
|
q7(4/5,r,b,c,k,1),
|
||
|
q7(5/5,r,b,c,k,1),
|
||
|
q7(5/5,r,b,c,k,-1),
|
||
|
q7(4/5,r,b,c,k,-1),
|
||
|
q7(3/5,r,b,c,k,-1),
|
||
|
q7(2/5,r,b,c,k,-1),
|
||
|
q7(1/5,r,b,c,k,-1),
|
||
|
q7(0/5,r,b,c,k,-1),
|
||
|
polar(r*0.9, r<b ? -k : 180/number_of_teeth),
|
||
|
polar(r, 181/number_of_teeth),
|
||
|
],
|
||
|
paths=[[2,3,4,5,6,7,8,9,10,11,12,13,14,15]]
|
||
|
);
|
||
|
}
|
||
|
translate([-c-1, -c-1, -2]) cube(size=[2*c+2, 2*c+2, 2]);
|
||
|
translate([-c-1, -c-1, thickness]) cube(size=[2*c+2, 2*c+2, 2]);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// Gear teeth without body
|
||
|
module gear_teeth(
|
||
|
mm_per_tooth = 3, //this is the "circular pitch", the circumference of the pitch circle divided by the number of teeth
|
||
|
number_of_teeth = 11, //total number of teeth around the entire perimeter
|
||
|
thickness = 6, //thickness of gear in mm
|
||
|
twist = 0, //teeth rotate this many degrees from bottom of gear to top. 360 makes the gear a screw with each thread going around once
|
||
|
pressure_angle = 28, //Controls how straight or bulged the tooth sides are. In degrees.
|
||
|
clearance = 0.0, //gap between top of a tooth on one gear and bottom of valley on a meshing gear (in millimeters)
|
||
|
backlash = 0.0 //gap between two meshing teeth, in the direction along the circumference of the pitch circle
|
||
|
) {
|
||
|
assign(pi = 3.1415926)
|
||
|
assign(p = mm_per_tooth * number_of_teeth / pi / 2) //radius of pitch circle
|
||
|
assign(c = p + mm_per_tooth / pi - clearance) //radius of outer circle
|
||
|
assign(b = p*cos(pressure_angle)) //radius of base circle
|
||
|
assign(r = p-(c-p)-clearance) //radius of root circle
|
||
|
assign(t = mm_per_tooth/2-backlash/2) //tooth thickness at pitch circle
|
||
|
assign(k = -iang(b, p) - t/2/p/pi*180) //angle to where involute meets base circle on each side of tooth
|
||
|
union() {
|
||
|
for (i = [0:number_of_teeth-1])
|
||
|
rotate([0,0,i*360/number_of_teeth])
|
||
|
linear_extrude(height = thickness, center = false, convexity = 10, twist = twist)
|
||
|
polygon(
|
||
|
points=[
|
||
|
[0, 0],
|
||
|
polar(r, -181/number_of_teeth),
|
||
|
polar(r*0.9, r<b ? k : -180/number_of_teeth),
|
||
|
q7(0/5,r,b,c,k,1),
|
||
|
q7(1/5,r,b,c,k,1),
|
||
|
q7(2/5,r,b,c,k,1),
|
||
|
q7(3/5,r,b,c,k,1),
|
||
|
q7(4/5,r,b,c,k,1),
|
||
|
q7(5/5,r,b,c,k,1),
|
||
|
q7(5/5,r,b,c,k,-1),
|
||
|
q7(4/5,r,b,c,k,-1),
|
||
|
q7(3/5,r,b,c,k,-1),
|
||
|
q7(2/5,r,b,c,k,-1),
|
||
|
q7(1/5,r,b,c,k,-1),
|
||
|
q7(0/5,r,b,c,k,-1),
|
||
|
polar(r*0.9, r<b ? -k : 180/number_of_teeth),
|
||
|
polar(r, 181/number_of_teeth),
|
||
|
],
|
||
|
paths=[[2,3,4,5,6,7,8,9,10,11,12,13,14,15]]
|
||
|
);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
// Same gear, but using recursion and experimental OpenSCAD vector
|
||
|
// concat() function which must be enabled at compile time with CONFIG+=experimental
|
||
|
// Clean and slightly faster
|
||
|
module gear_concat(
|
||
|
mm_per_tooth = 3, //this is the "circular pitch", the circumference of the pitch circle divided by the number of teeth
|
||
|
number_of_teeth = 11, //total number of teeth around the entire perimeter
|
||
|
thickness = 6, //thickness of gear in mm
|
||
|
twist = 0, //teeth rotate this many degrees from bottom of gear to top. 360 makes the gear a screw with each thread going around once
|
||
|
pressure_angle = 28, //Controls how straight or bulged the tooth sides are. In degrees.
|
||
|
clearance = 0.0, //gap between top of a tooth on one gear and bottom of valley on a meshing gear (in millimeters)
|
||
|
backlash = 0.0 //gap between two meshing teeth, in the direction along the circumference of the pitch circle
|
||
|
) {
|
||
|
assign(pi = 3.1415926)
|
||
|
assign(p = mm_per_tooth * number_of_teeth / pi / 2) //radius of pitch circle
|
||
|
assign(c = p + mm_per_tooth / pi - clearance) //radius of outer circle
|
||
|
assign(b = p*cos(pressure_angle)) //radius of base circle
|
||
|
assign(r = p-(c-p)-clearance) //radius of root circle
|
||
|
assign(t = mm_per_tooth/2-backlash/2) //tooth thickness at pitch circle
|
||
|
assign(k = -iang(b, p) - t/2/p/pi*180) //angle to where involute meets base circle on each side of tooth
|
||
|
linear_extrude(height = thickness, center = false, convexity = 10, twist = twist)
|
||
|
polygon(
|
||
|
points = gear_points(r, b, c, k, number_of_teeth, number_of_teeth),
|
||
|
paths = [ range(15*(number_of_teeth)) ]
|
||
|
);
|
||
|
};
|
||
|
|
||
|
function gear_points(r, b, c, k, number_of_teeth, i) =
|
||
|
(i <= 0 ? [] : concat(
|
||
|
gear_points(r, b, c, k, number_of_teeth, i-1),
|
||
|
tooth_base_points(r, b, c, k, number_of_teeth, i)
|
||
|
));
|
||
|
|
||
|
function tooth_base_points(r, b, c, k, number_of_teeth, i) =
|
||
|
(r < b ? concat(
|
||
|
[ polar(r, i*360/number_of_teeth + k) ],
|
||
|
tooth_points(r, b, c, k, number_of_teeth, i),
|
||
|
[ polar(r, i*360/number_of_teeth - k),
|
||
|
polar(r, i*360/number_of_teeth + 180/number_of_teeth) ]
|
||
|
) : concat(
|
||
|
tooth_points(r, b, c, k, number_of_teeth, i),
|
||
|
[ polar(r, i*360/number_of_teeth + 180/number_of_teeth) ]
|
||
|
));
|
||
|
|
||
|
function tooth_points(r, b, c, k, number_of_teeth, i) = [
|
||
|
q7r(0/5,r,b,c,k,1,i*360/number_of_teeth),
|
||
|
q7r(1/5,r,b,c,k,1,i*360/number_of_teeth),
|
||
|
q7r(2/5,r,b,c,k,1,i*360/number_of_teeth),
|
||
|
q7r(3/5,r,b,c,k,1,i*360/number_of_teeth),
|
||
|
q7r(4/5,r,b,c,k,1,i*360/number_of_teeth),
|
||
|
q7r(5/5,r,b,c,k,1,i*360/number_of_teeth),
|
||
|
q7r(5/5,r,b,c,k,-1,i*360/number_of_teeth),
|
||
|
q7r(4/5,r,b,c,k,-1,i*360/number_of_teeth),
|
||
|
q7r(3/5,r,b,c,k,-1,i*360/number_of_teeth),
|
||
|
q7r(2/5,r,b,c,k,-1,i*360/number_of_teeth),
|
||
|
q7r(1/5,r,b,c,k,-1,i*360/number_of_teeth),
|
||
|
q7r(0/5,r,b,c,k,-1,i*360/number_of_teeth),
|
||
|
];
|
||
|
|
||
|
function range(n) = (n >= 0 ? concat(range(n-1), [n]) : []);
|
||
|
|
||
|
// radius a fraction f up the curved side of the tooth, rotated at 'rot' angle
|
||
|
function q7r(f,r,b,r2,t,s,rot) = q6r(b,s,t,(1-f)*max(b,r)+f*r2,rot);
|
||
|
// point at radius d on the involute curve, rotated at 'rot' angle
|
||
|
function q6r(b,s,t,d,rot) = polar(d,rot+s*(iang(b,d)+t));
|
||
|
|
||
|
|
||
|
|
||
|
// Original gear() module
|
||
|
// Teeth shape is good, but the body is composed from individual sectors;
|
||
|
// this sometimes results in bad "degenerate" faces due to floating point issues.
|
||
|
// Can be checked with FreeCAD 'mesh evaluation'
|
||
|
module gear_original(
|
||
|
mm_per_tooth = 3, //this is the "circular pitch", the circumference of the pitch circle divided by the number of teeth
|
||
|
number_of_teeth = 11, //total number of teeth around the entire perimeter
|
||
|
thickness = 6, //thickness of gear in mm
|
||
|
hole_diameter = 0, //diameter of the hole in the center, in mm
|
||
|
twist = 0, //teeth rotate this many degrees from bottom of gear to top. 360 makes the gear a screw with each thread going around once
|
||
|
teeth_to_hide = 0, //number of teeth to delete to make this only a fraction of a circle
|
||
|
pressure_angle = 28, //Controls how straight or bulged the tooth sides are. In degrees.
|
||
|
clearance = 0.0, //gap between top of a tooth on one gear and bottom of valley on a meshing gear (in millimeters)
|
||
|
backlash = 0.0 //gap between two meshing teeth, in the direction along the circumference of the pitch circle
|
||
|
) {
|
||
|
assign(pi = 3.1415926)
|
||
|
assign(p = mm_per_tooth * number_of_teeth / pi / 2) //radius of pitch circle
|
||
|
assign(c = p + mm_per_tooth / pi - clearance) //radius of outer circle
|
||
|
assign(b = p*cos(pressure_angle)) //radius of base circle
|
||
|
assign(r = p-(c-p)-clearance) //radius of root circle
|
||
|
assign(t = mm_per_tooth/2-backlash/2) //tooth thickness at pitch circle
|
||
|
assign(k = -iang(b, p) - t/2/p/pi*180) //angle to where involute meets base circle on each side of tooth
|
||
|
difference() {
|
||
|
for (i = [0:number_of_teeth-teeth_to_hide-1])
|
||
|
rotate([0,0,i*360/number_of_teeth])
|
||
|
linear_extrude(height = thickness, center = false, convexity = 10, twist = twist)
|
||
|
polygon(
|
||
|
points=[
|
||
|
[0, -hole_diameter/10],
|
||
|
polar(r, -181/number_of_teeth),
|
||
|
polar(r, r<b ? k : -180/number_of_teeth),
|
||
|
q7(0/5,r,b,c,k, 1),q7(1/5,r,b,c,k, 1),q7(2/5,r,b,c,k, 1),q7(3/5,r,b,c,k, 1),q7(4/5,r,b,c,k, 1),q7(5/5,r,b,c,k, 1),
|
||
|
q7(5/5,r,b,c,k,-1),q7(4/5,r,b,c,k,-1),q7(3/5,r,b,c,k,-1),q7(2/5,r,b,c,k,-1),q7(1/5,r,b,c,k,-1),q7(0/5,r,b,c,k,-1),
|
||
|
polar(r, r<b ? -k : 180/number_of_teeth),
|
||
|
polar(r, 181/number_of_teeth),
|
||
|
],
|
||
|
paths=[[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]]
|
||
|
);
|
||
|
cylinder(h=2*thickness+1, r=hole_diameter/2, center=true, $fn=20);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// these 4 functions are used by gear
|
||
|
function polar(r,theta) = r*[sin(theta), cos(theta)]; //convert polar to cartesian coordinates
|
||
|
function iang(r1,r2) = sqrt((r2/r1)*(r2/r1) - 1)/3.1415926*180 - acos(r1/r2); //unwind a string this many degrees to go from radius r1 to radius r2
|
||
|
function q7(f,r,b,r2,t,s) = q6(b,s,t,(1-f)*max(b,r)+f*r2); //radius a fraction f up the curved side of the tooth
|
||
|
function q6(b,s,t,d) = polar(d,s*(iang(b,d)+t)); //point at radius d on the involute curve
|