// // wedge.scad // 2026-03-06 ChatGPT // $Header$ // // Render preview: // openscad color_wedge_chart.scad // // Export STL from command line: // openscad -o color_wedge_chart_20260306_0000.stl color_wedge_chart.scad // $fn = 120; // ------------------------------------------------------------ // Global parameters // ------------------------------------------------------------ slice_count = 10; slice_angle = 360 / slice_count; // 36 degrees explode_gap = 12; inner_r = 18; outer_r = 78; thickness = 5; // Crown shaping cap_z0 = thickness; cap_z1 = thickness + 3; cap_z2 = thickness + 7; cap_z3 = thickness + 5; // Radial positions controlling the top profile cap_r0 = inner_r + 6; cap_r1 = inner_r + 18; cap_r2 = outer_r - 18; cap_r3 = outer_r - 4; // Text label_size = 8; label_height = 1.2; label_font = "Liberation Sans:style=Bold"; // Small epsilon for clean CSG eps = 0.05; // ------------------------------------------------------------ // 2D annular wedge sector // Angle starts at 0 and runs to ang degrees // ------------------------------------------------------------ module wedge_2d(r1, r2, ang, step=2) { pts = concat( [ for (a = [0:step:ang]) [r2*cos(a), r2*sin(a)] ], [ for (a = [ang:-step:0]) [r1*cos(a), r1*sin(a)] ] ); polygon(points = pts); } // ------------------------------------------------------------ // Thin radial band of the wedge // Used for hull() operations to create faceted crown surfaces // ------------------------------------------------------------ module wedge_band(r1, r2, ang, z, h=eps) { translate([0,0,z]) linear_extrude(height = h) wedge_2d(r1, r2, ang); } // ------------------------------------------------------------ // Base body of the wedge // ------------------------------------------------------------ module wedge_base() { linear_extrude(height = thickness) wedge_2d(inner_r, outer_r, slice_angle); } // ------------------------------------------------------------ // Simple faceted cap // This is the starter version of the crown. // It creates a raised table-like region and sloped sides. // ------------------------------------------------------------ module wedge_cap_simple() { union() { hull() { wedge_band(cap_r0, cap_r1, slice_angle, cap_z0); wedge_band(cap_r1, cap_r2, slice_angle, cap_z1); } hull() { wedge_band(cap_r1, cap_r2, slice_angle, cap_z1); wedge_band(cap_r2, cap_r3, slice_angle, cap_z2); } hull() { wedge_band(cap_r2, cap_r3, slice_angle, cap_z2); wedge_band(cap_r3, outer_r, slice_angle, cap_z3); } } } // ------------------------------------------------------------ // Raised number on underside // Number is centered approximately on the wedge centerline. // ------------------------------------------------------------ module wedge_label(idx) { mid_r = (inner_r + outer_r) / 2; mid_a = slice_angle / 2; x = mid_r * cos(mid_a); y = mid_r * sin(mid_a); translate([x, y, 0]) mirror([0,0,1]) translate([0,0,label_height]) rotate([180,0,mid_a - 90]) linear_extrude(height = label_height) text(str(idx), size = label_size, halign = "center", valign = "center", font = label_font); } // ------------------------------------------------------------ // Single wedge object // ------------------------------------------------------------ module wedge_unit(idx=0) { union() { wedge_base(); wedge_cap_simple(); wedge_label(idx); } } // ------------------------------------------------------------ // Full 10-part exploded wheel // Each wedge is translated outward along its own centerline. // ------------------------------------------------------------ module wheel_10() { for (i = [0:slice_count-1]) { a = i * slice_angle; mid_a = a + slice_angle/2; dx = explode_gap * cos(mid_a); dy = explode_gap * sin(mid_a); translate([dx, dy, 0]) rotate([0,0,a]) wedge_unit(i); } } // ------------------------------------------------------------ // Top-level render // ------------------------------------------------------------ wheel_10();