//hirth8 /* make profile of cutter path bore centre hole and recess in workpiece angle work piece cut tapered grooves note that depth of grooves and number are related */ od = 60;// overall diameter pangle = 90;// profile angle of cutter ng = 17; // number of grooves bore = 10; //bore diameter recessdiam = 20;//recess diameter recesst = 10; //height from back to recess thick = 20; //thickness of plate cw = 30; // cutter width cr = 0.4; // cutter tip radius fl = 0.6; // flatten depth //////////////////////////////// $fn=100; // prepare blank module blank(){ difference(){ cylinder(d=od,h=thick); cylinder (d=bore,h=3*thick); translate([0,0,recesst]) cylinder (d=recessdiam,h=thick); } } //make cutter path (basic sharp V tool module cutter_profile(){ op=tan((180-pangle)/2)*cw/2; points=[[0,-cw/2],[op,0],[0,cw/2]]; translate([-op,0,0]) polygon (points); } module path(){ rotate([0,90,0]) linear_extrude(od*0.75) offset(r=cr) // to give effect of rounded cutter edge cutter_profile(); } /* let depth of groove at edge of blank be named 'depth'. There are ng grooves, such as at the top edge of the circumference of the blank, the edges of path meet. The vertical distance between the top of the cylinder, and bottom of groove at the edge of the blank will be 'depth'. At the centre of the blank, at the top face, then depth will also be the same, and the grrove sides would not be radial. But in order to get two identical meshing pieces, then that centre depth must be half the outer 'depth'. This can be achieved by placing the blank at an angle to the cutter path, using a rotary table, and rotating it ng steps to make ng radial cuts. The cutter width must be greater than the groove width. */ /* distance between peaks of ridges at circumference will be length of chord. chord = diameter * sin(angle/2) and depth of groove = (chord/2)/tan(pangle/2) */ chord=od*sin(0.5*360/ng); echo(chord=chord); dg= (chord/2)/tan(pangle/2); echo (dg=dg); // angle for rotary table is art = asin(dg*2/od); echo(art=art); // position rotary table // move so that centre is aligned module positionedblank(){ translate([0,0,-thick+dg/2])blank(); } // tilt rotary table module tilted(){ rotate([0,-art,0])positionedblank(); } // make groove module demogroove(){ translate ([100,0,0]) difference(){ tilted(); # path(); } } // rotate cylinder 360/ng degrees //instead of rotating the blank, we can rotate and angle the cutter path module single(){ difference(){ translate([0,0,-thick+dg/2])blank(); for(j=[0:360/ng:360]){ rotate([0,0,j]) rotate([0,art/2,0])path();} } } translate([-od*5.3,0,0])demogroove(); translate([-od*1.2,0,0])single(); translate([-od*2.4,0,0])rotate([0,-art,0]) single(); /* Test of result. Invert and space, check for parallel faces to groove (note that this test only works for odd number of grooves. If even number of grooves, then you will need to rotate one piece by half a groove width) */ module test(){ difference(){ union(){ single(); translate([0,0,-2.5]) // set z to show // edges rotate([0,180,0]) single(); } translate([0,0,-100]) cube(500); } } test(); /* extra info. It is essential, if wanting the two matching, parts, that the angle of the rotary table is precise. The tooling profile will have a rounded edge, but that makes no difference wrt the angles. Generally, the top of the ridges would be machined off, so that the pointed ridges do not rest on the bottom of the grooves. If the V tool is a grinding disc, then the end of the tool path will be circular. It will therefore travel past the centre of the workpiece, but because of the angle, it will not collide with the far edge of the recess (if it is an equal number of grooves, then it can overlap for a certain distance.) */ // Now flatten the ridges module flatpath(){ // tool 5mm wide, flat bottom translate([0,-2.5,0]) // centre over ridge cube([od*1.5,5,15]); } module flatten(){ difference(){ translate([0,0,fl+fl]) single(); for(j=[0:360/ng:360]){ rotate([0,0,j+180/ng]) rotate([0,-art/2,0])flatpath(); } } } module testflatten(){ difference(){ union(){ flatten(); translate([0,0,1.7]) // set z to show // edges rotate([0,180,0]) flatten(); } translate([0,0,-100]) cube(500); } } translate([od+10,0,0]) flatten(); translate([2*od+20,0,0]) testflatten();