inner_dia = 70; outer_dia = 75; wall_thickness = (outer_dia-inner_dia)/2; nub_thickness = 2; nub_height = 1; nub_width = 18; connector_height = 15; curve_angle = 45; connector_dist = 5; $fn=100; module nub(width, height, thickness, dia){ radius = 0.5; new_thickness = thickness - radius*2; translate([0,0,-1.8]) minkowski() { intersection(){ linear_extrude(5) translate([-width/2,0,0]) polygon(points=[[0,0],[width/4,new_thickness],[3*width/4,new_thickness],[width,0]]); translate([0,0,-outer_dia/2+3]) rotate([90,0,0]) difference(){ cylinder(r=outer_dia/2, h=10, center=true, $fn=50); cylinder(r=outer_dia/2-height, h=10, center=true, $fn=50); } } sphere(r=radius, $fn=20); } } module connector(inner_dia, outer_dia, height){ translate([0,0, height/2]){ difference(){ cylinder(r=outer_dia/2, h=height, center=true); cylinder(r=inner_dia/2, h=height+0.01, center=true); } translate([0,-outer_dia/2+0.3,height-15]) rotate([90,0,0]) nub(nub_width, nub_height, nub_thickness, outer_dia); rotate([0,0,180]) translate([0,-outer_dia/2+0.3,height-15]) rotate([90,0,0]) nub(nub_width, nub_height, nub_thickness, outer_dia); } } module tCyls(outer_dia, height_factor = 1){ union(){ cylinder(r=outer_dia/2, h=outer_dia*height_factor, center=true); translate([0,outer_dia*height_factor/4,0]) rotate([90, 0, 0]) cylinder(r=outer_dia/2, h=outer_dia/2*height_factor, center=true); } } module tPiece(inner_dia, outer_dia){ difference(){ tCyls(outer_dia); tCyls(inner_dia, height_factor=1.5); } } module tSplitter(inner_dia, outer_dia, connector_height){ union(){ tPiece(inner_dia, outer_dia); translate([0,0,outer_dia/2]) rotate([0,0,90]) connector(inner_dia, outer_dia, connector_height); translate([0,outer_dia/2,0]) rotate([-90,0,0]) rotate([0,0,90]) connector(inner_dia, outer_dia, connector_height); translate([0,0,-outer_dia/2]) rotate([180,0,0]) rotate([0,0,90]) connector(inner_dia, outer_dia, connector_height); } } function custom_y(w, angle) = (w/2-w*(1-cos(angle)))/tan(angle)+w*sin(angle); module one_side(r, w, angle){ rotate_extrude(angle=angle) translate([w/2,0,0]) circle(r=r); y = custom_y(w, angle); translate([w/2,y,0]) rotate(angle) mirror([1,0,0]) rotate_extrude(angle=angle) translate([w/2,0,0]) circle(r=r); tri_x = w/2-w*(1-cos(angle)); tri_y = tri_x/tan(angle); length = sqrt(pow(tri_y, 2) + pow(tri_x,2)); rotate(angle,[0,0,1]) translate([w/2,length,0]) rotate(90,[1,0,0]) linear_extrude(length) circle(r=r); } module split_shape(r, w, angle){ union(){ one_side(r,w,angle); mirror([1,0,0]) one_side(r,w,angle); } } module yTubes(inner_dia, wall_thickness, curve_angle, connector_dist){ my_w = inner_dia+2*wall_thickness+connector_dist; difference(){ split_shape(inner_dia/2+wall_thickness, my_w, curve_angle); split_shape(inner_dia/2, my_w, curve_angle); } } module ySplitter(inner_dia, wall_thickness, curve_angle, connector_height, connector_dist){ union(){ yTubes(inner_dia, wall_thickness, curve_angle, connector_dist); translate([0,outer_dia-2,0]) rotate([-90,0,0]) rotate([0,0,90]) connector(inner_dia, outer_dia, connector_height); translate([outer_dia/2+connector_dist/2,0,0]) rotate([90,0,0]) connector(inner_dia, outer_dia, connector_height); translate([-outer_dia/2-connector_dist/2,0,0]) rotate([90,0,0]) connector(inner_dia, outer_dia, connector_height); } } // connector(inner_dia, outer_dia, connector_height); // nub(nub_width, nub_height, nub_thickness, outer_dia); // tSplitter(inner_dia, outer_dia, connector_height); ySplitter(inner_dia, wall_thickness, curve_angle, connector_height, connector_dist);