//s=0.001; // Very small number for trivial offsets mm_per_inch=25.4; // Scale by this to make imperial things metric // when come back bring... M_PI=3.1415926535897932384626433832795028841971693993751058209; GRID_FINE=0.01; function fragments(r,fn,fs,fa) = (r < GRID_FINE)?3: (fn > 0.0)?(fn >= 3 ? fn : 3): ceil(max(min(360.0 / fa, r*2*M_PI / fs), 5)); // Push Y, parallel Z module skew_yz(a) { multmatrix(m= [ [ 1, 0, 0, 0], [tan(a), 1, 0, 0], [ 0, 0, 1, 0], [ 0, 0, 0, 1] ]) child(0); } module skew_zy(a) { // Push Z, parallel Y multmatrix(m = [ [1, 0, 0, 0], [0, 1, 0, 0], [tan(a), 0, 1, 0], [0, 0, 0, 1] ]) child(0); } module skew_xz(a) { // Push X, parallel Z multmatrix(m = [ [1, tan(a), 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1] ]) child(0); } module skew_zx(a) { // Push Z, parallel X multmatrix(m = [ [1, 0, 0, 0], [0, 1, 0, 0], [0, tan(a), 1, 0], [0, 0, 0, 1] ]) child(0); } module skew_xy(a) { // Push X parallel Y multmatrix(m = [ [1, 0, tan(a), 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1] ]) child(0); } // Push Y, parallel X module skew_yx(a) { multmatrix(m = [ [1, 0, 0, 0], [0, 1, tan(a), 0], [0, 0, 1, 0], [0, 0, 0, 1] ]) child(0); } // Torus, specified by radius and thickness module torus(r, t) rotate_extrude(convexity=4) translate([r,0,0]) circle(t); // Another torus, specified like they do O-rings, with inner and outer diameters module oring(ir, or, s=0) torus((ir+or)/4, ((or-ir)/4) + s); // Try radial(8, [2,0,0]) cube([1,1,1]); to see what this does. module radial(n=8, o=[0,0,0], a=360, ao=0) for(x=[0:n-1]) rotate([0,0,ao+(a*(x/n))]) translate(o) child(0); // Try array(10, 2, [2,0,0], [3,0,0]) cube([1,1,1]); to see what this does. module array(n=10, m=1, on=[1,0,0], om=[0,1,0]) { for(y=[0:m-1]) for(x=[0:n-1]) translate((on*x)+(om*y)) child(0); } // Like mirror(), except both the original and the mirrored are created. // 'off' lets you move the plane of the mirror. module mirrordup(plane, off=[0,0,0]) { /* translate(-off/2) child(0); translate(off/2) mirror(plane) child(0);*/ child(0); translate(off) mirror(plane) child(0); } // Like mirrordup() but hulls the space between module hulldup(plane, off=[0,0,0]) hull() { translate(-off/2) child(0); translate(off/2) mirror(plane) child(0); } // A hole or rod of d diameter, like hex(6) will fit a 6mm hex key module hex(d,l=1) { r=d/2; rotate_extrude($fn=6) polygon([ [0,0], [0,l], [r/cos(30),l], [r/cos(30),0] ]); } // A ring with a square cross-section, like a cylinder with a hole module ring(r1, r2, h, center=false) { if(center) translate([0,0,-(h/2)]) rotate_extrude() polygon(points=[ [r1, 0], [r1, h], [r2, h], [r2, 0] ]); else rotate_extrude() polygon(points=[ [r1, 0], [r1, h], [r2, h], [r2, 0] ], center=center); } // A cube with rounded edges. CPU-intensive. module roundcube(v2=[1,1,1], r=0.1) { v=[v2[0]-(2*r), v2[1]-(2*r), v2[2]-(2*r)]; translate([r,r,r]) union() { minkowski() { cube([v[0],v[1],v[2]]); cylinder(r=r, h=s); } minkowski() { cube([v[0],v[1],v[2]]); rotate([90, 0,0]) cylinder(r=r, h=s); } minkowski() { cube([v[0],v[1],v[2]]); rotate([0,90,0]) cylinder(r=r, h=s); } for(q = [ [0,0,0], [0,0,1], [0,1,0], [0,1,1], [1,0,0], [1,0,1], [1,1,0], [1,1,1] ]) translate([v[0]*q[0],v[1]*q[1],v[2]*q[2]]) sphere(r=r); } } /** * Works just like cylinder() except it takes a 'bevel' option which cuts * 45-degree bevels on the top and bottom faces, like * /------\ * | | * | | * \______/ * The bigger the number, the bigger the bevel. */ module bcylinder(r=10, h=10, bevel=0, center=false) { if(bevel == 0) cylinder(r=r, h=h, center=center); else translate([0,0,center?0:h/2]) rotate_extrude() assign(a=r, b=r-bevel, t=h/2, y=(h/2)-bevel, u=-(h/2)+bevel, i=-(h/2)) polygon([ [a,y], [a,u], [b,i], [0,i], [0,t], [b,t]]); } module pie(r, a1=0, a2=90, msteps=100) { function a(n)=90-(a1+((a2-a1)*(n/msteps))); polygon(concat([[0,0]], [ for(n=[0:msteps]) r*[sin(a(n)),cos(a(n))] ])); } // An extruded trapezoid for dovetail shapes module dovetail(w1, w2, h, l) { linear_extrude(l) polygon([ [w1/2,0], [w2/2,h], [-w2/2, h], [-w1/2,0] ]); } // like dovetail, but rounded module flange(r1, r2, h1, h2, l) { hull() { cylinder(r=r1, h=h1); translate([l-(r1+r2),0,0]) cylinder(r=r2, h=h2); } } // Translate an object along a radius and angle without rotating // the object itself module traj(a=90, r=1) translate([sin(a)*r, cos(a)*r, 0]) child(0); // Mirrors objects then takes their intersection. // Try mirrorintersect([1,0,0]) translate([5,0,0]) cylinder(r=10); module mirrorintersect(plane, off=[0,0,0]) intersection() { child(0); translate(off) mirror(plane) child(0); } // Lens in the geometry sense -- the intersection of two circles. // r is the radius of the cylinders, d is the amount of overlap // from 0=none to 1=total. // // Can also do intersections of spheres via 'sphere=true'. module lens(r, d, h=1, sphere=false, center=false) { if(sphere == true) mirrorintersect([1,0,0]) translate(r*[1-d,0,0]) sphere(r=r); else mirrorintersect([1,0,0]) translate(r*[1-d,0,0]) cylinder(r=r, h=h, center=center); } // Reduces one level of array elements, i.e. // [ [ [1,2], [3,4] ], [ [5,6], [7,8] ] ] into [ [1,2],[3,4],[5,6],[7,8] ] // This lets you cram more than one element into a for() and get a legit array out. function flat(A,P=0)=((P+1)