$fn = 50; // For smooth curves // --- Helper Functions --- function add(a, b) = [a[0] + b[0], a[1] + b[1]]; function sub(a, b) = [a[0] - b[0], a[1] - b[1]]; function scale(a, s) = [a[0] * s, a[1] * s]; function length(a) = sqrt(a[0] * a[0] + a[1] * a[1]); function normalize(a) = let(n = length(a)) (n == 0 ? [0, 0] : [a[0] / n, a[1] / n]); // --- Arc Generation --- function arc(center, r, start_angle, end_angle, segments) = [for (i = [0:segments - 1]) let(a = start_angle + i * (end_angle - start_angle) / (segments - 1)) [center[0] + r * cos(a), center[1] + r * sin(a)]]; // --- Fillet at a Vertex --- function fillet(v, v_prev, v_next, wt, seg) = let( u1 = normalize(sub(v, v_prev)), u2 = normalize(sub(v_next, v)), n1 = [u1[1], -u1[0]], // Outward normal for incoming edge n2 = [u2[1], -u2[0]], // Outward normal for outgoing edge T1 = add(v, scale(n1, wt)), // Tangent point on incoming edge T2 = add(v, scale(n2, wt)), // Tangent point on outgoing edge angle1 = atan2(T1[1] - v[1], T1[0] - v[0]), angle2 = atan2(T2[1] - v[1], T2[0] - v[0]), angle2_mod = (angle2 < angle1) ? angle2 + 360 : angle2, arc_pts = arc(v, wt, angle1, angle2_mod, seg) ) arc_pts; // --- Fillet Polygon --- function fillet_polygon(poly, wt, seg) = [for (i = [0:len(poly) - 1]) let( v = poly[i], v_prev = poly[(i + len(poly) - 1) % len(poly)], v_next = poly[(i + 1) % len(poly)], arc_pts = fillet(v, v_prev, v_next, wt, seg) ) arc_pts]; // --- Main Function --- function fillet_polygon_points(points_list1, wt, arc_segments) = let( rn = fillet_polygon(points_list1, wt, arc_segments) ) [for (sublist = rn, point = sublist) point]; // --- Example Usage --- points_list1 = [[-10, -10], [30, -5], [10, 10], [-10, 10]]; // Base polygon wt = 15; // Fillet (wall thickness) radius at each vertex arc_segments = 50; // Number of points to generate along each fillet arc pl2 = fillet_polygon_points(points_list1, wt, arc_segments); echo(pl2 = pl2); // Draw the final rounded polygon. difference() { polygon(pl2); polygon(points_list1); }