module triangularPrism(angle, side1, side2, height) { linear_extrude(height) polygon(points = [[0, 0], [0, side1], [side2 * sin(angle), side2 * cos(angle)]]); } module arcCylinder(outerRadius, height, degrees, innerRadius = 0, center = false) { epsilon = 0.01; degToCut = 360 - (degrees % 360); triDeg = degToCut % 60; triSideLen = (outerRadius + epsilon) / cos(triDeg / 2); fullTriSide = (outerRadius + epsilon) / cos(30); numFullTriangles = floor(degToCut / 60); difference() { // Main cylinder body cylinder(h=height, r=outerRadius); // Exclusion translate([0, 0, -1*epsilon]) union() { // Inner cylinder (to form hole creating the wall) if (innerRadius > 0) { cylinder(h=height + 2*epsilon, r=max(0, innerRadius)); } // Partial circle cut-out if (degToCut < 360) { rotate([0, 0, -90 - 60 * numFullTriangles]) union() { // All 60-degree cuts get an eqilateral triangle. if (degToCut >= 60) { for (i = [1:numFullTriangles]) { // rotate([-60 * i, 0, 0]) mirror([0, 1, 0]) cube([cubeSideLen, cubeSideLen, height + 2*epsilon]); rotate([0, 0, 60 * i]) triangularPrism( angle = 60.1, side1 = fullTriSide, side2 = fullTriSide, height = height + 2*epsilon); } } // Cut out the remaining angle with a triangular prism rotate([0, 0, 0.1]) triangularPrism( angle = triDeg + 0.1, side1 = triSideLen, side2 = triSideLen, height = height + 2*epsilon); } } } } }