diff --git a/band.scad b/band.scad index fd6340b..4b24989 100644 --- a/band.scad +++ b/band.scad @@ -2,99 +2,120 @@ include ; $fn = $preview ? 32 : 128; -band_arc_radius = 65; -thickness = 3; -height = 10; -band_arc = 240; +band_arc_radius = 75; +band_thickness = 3; +band_height = 10; leg_length = 27; edge_radius = 0.5; -punch_angles = [-95, -70, -45, 0, 45, 70, 95]; -tooth_width=2; -tooth_height=2.5; -teeth_max_angle = 110; -teeth_spacing = 2.5; -punch_clearance = 5; -module tooth() { +band_arc = turtle([ + "move", leg_length, + "arcright", band_arc_radius, 80, + "arcright", band_arc_radius * 0.8, 20, + "arcright", band_arc_radius * 1.2, 40, + "arcright", band_arc_radius * 0.8, 20, + "arcright", band_arc_radius, 80, + "move", leg_length +]); +band_profile = rect( + size=[band_thickness, band_height], + rounding=edge_radius +); +band_length = path_length(band_arc); +band_curve_length = band_length-leg_length*2; +leg_frac = leg_length/band_length; +band_curve_frac = 1-leg_frac*2; + +tooth_width = 2; +tooth_height = 2.5; +tooth_offset = band_height/2-2; +dense_teeth_count = 70; +teeth_step = band_curve_frac/dense_teeth_count; + +punch_fracs = [ + for(frac=[0.07, 0.18, 0.29, 0.5, 0.71, 0.82, 0.93]) + frac * band_curve_frac + leg_frac +]; + +function hole(anchor) = rect( + size=[band_height/2+1, band_height/2], + rounding=band_height/4, + anchor=anchor +); + +module punch() linear_sweep( + region=[ + right(1, p=hole(LEFT)), + left(1, p=hole(RIGHT)) + ], + length=band_thickness+2 +); + +function punch_clearance(tooth_frac, punch_frac) = abs(punch_frac - tooth_frac) > 0.025; + +module punches() + for(punch_frac=punch_fracs) + sweep_attach( + parent=LEFT, + child=BOT, + frac=punch_frac, + spin=90, + overlap=band_thickness+1 + ) + tag("remove") + punch(); + +module tooth() cyl( d1=tooth_width, d2=edge_radius*2, h=tooth_height, - rounding2=edge_radius, - anchor=BOT, - orient=FWD + rounding2=edge_radius ); -} -module punch() { - region = right( - 1, - p=rect( - [height/2+1, height/2], - rounding=height/4, - anchor=LEFT - ) - ); - linear_sweep( - [region, xflip(region)], - length=thickness+2, - center=true, - orient=BACK - ); -} - - -module band() { - region = right( - band_arc_radius, - p=rect( - [thickness, height], - rounding=edge_radius - ) - ); - rotate_sweep( - region, - angle=band_arc, - spin=-band_arc/2+90 - ); -} - -module leg() { - rotate(-band_arc/2+90) - right(band_arc_radius) - cuboid( - [thickness, leg_length, height], - rounding=edge_radius, - edges="Y", - anchor=BACK +module teeth() + for(tooth_frac=[leg_frac:teeth_step:1-leg_frac]) + if( + all([ + for (punch_frac=punch_fracs) + punch_clearance(tooth_frac, punch_frac) + ]) ) - attach(FWD) - xcyl( - thickness, - d=height, - rounding=edge_radius - ); -} + sweep_attach(LEFT, BOT, tooth_frac) { + left(tooth_offset) tooth(); + right(tooth_offset) tooth(); + } -difference() { - union() { - band(); - leg(); - xflip() leg(); - } - for(a=punch_angles) { - zrot(a) back(band_arc_radius) punch(); - } -} +pip_count = 4; +pip_size = 1.2; +pip_frac_step = 0.0045; -for(a=[-teeth_max_angle:teeth_spacing:teeth_max_angle]) { - if(all([ - for (b=punch_angles) - abs(b - a) > punch_clearance - ])) { - zrot(a) back(band_arc_radius-thickness/2+0.1) { - up(height/4) tooth(); - down(height/4) tooth(); - }; +module pips() + for(pip_idx=[0:1:pip_count-1]) + sweep_attach( + parent=LEFT, + child=BOT, + frac=leg_frac+pip_idx*pip_frac_step, + overlap=pip_size/2 + ) + tag("remove") + sphere(d=pip_size); + +module ends() + attach(["end", "start"]) + xcyl( + h=band_thickness, + d=band_height, + rounding=edge_radius + ); + +module band() + diff() + path_sweep(band_profile, band_arc) { + punches(); + teeth(); + pips(); + ends(); } -} + +band();