module spreizkonus( part, d, sd, mount=0, bottom=1) { assert( "bottom" == part || "top" == part, "First parameter (part) must be \"bottom\" or \"top\"."); s = mount; b = bottom; h = d+s+b; c = 1 + sqrt( 2*h^2); m = "bottom" == part ? 180+45 : 45; v = "bottom" == part ? sd : 0; difference() { intersection() { translate( [0,0,s/2-b/2]) cylinder( d=d, h=h, center=true); rotate( [0,m,0]) translate( [0,0,c/2]) cube( c, center=true); } translate( [0,0,s/2-b/2]) hull() { cylinder( d=sd, h=h+1, center=true); translate( [v,0,0]) cylinder( d=sd, h=h+1, center=true); } } } /* spreizkonus( "bottom", d=30, sd=4, bottom=2); translate([0,0,1]) spreizkonus( "top", d=30, sd=4, mount=2); */