From c5dc13508ad8621f6e3bd3383dfe31aa388ab10f Mon Sep 17 00:00:00 2001 From: John Poole Date: Fri, 6 Mar 2026 10:55:49 -0800 Subject: [PATCH] works, but text is "cut" and hidden, committing now before removing "cut" and replacing with "raised" --- scad/wedge.scad | 252 +++++++++++++++++++++++++++++------------------- 1 file changed, 153 insertions(+), 99 deletions(-) diff --git a/scad/wedge.scad b/scad/wedge.scad index dd48074..f7c6f10 100644 --- a/scad/wedge.scad +++ b/scad/wedge.scad @@ -1,150 +1,204 @@ // -// wedge.scad +// colorpie.scad // 2026-03-06 ChatGPT // $Header$ // -// Render preview: -// openscad color_wedge_chart.scad +// Preview: +// openscad colorpie.scad // -// Export STL from command line: -// openscad -o color_wedge_chart_20260306_0000.stl color_wedge_chart.scad +// STL export: +// openscad -o colorpie_20260306_0834.stl colorpie.scad // -$fn = 120; +$fn = 90; // ------------------------------------------------------------ // Global parameters // ------------------------------------------------------------ slice_count = 10; -slice_angle = 360 / slice_count; // 36 degrees -explode_gap = 12; +slice_angle = 360 / slice_count; // 36 degrees +explode_gap = 10; -inner_r = 18; -outer_r = 78; -thickness = 5; +// Footprint +inner_r = 22; +outer_r = 82; +thickness = 6; -// Crown shaping -cap_z0 = thickness; -cap_z1 = thickness + 3; -cap_z2 = thickness + 7; -cap_z3 = thickness + 5; +// Crown profile across the wedge width +crown_height = 10; +table_frac = 0.42; // fraction of width occupied by table +shoulder_frac = 0.18; // fraction on each side used by bevel/shoulder +stations = 13; // more stations = more facet slices across width -// 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 +// Labeling label_size = 8; -label_height = 1.2; +label_depth = 1.0; label_font = "Liberation Sans:style=Bold"; -// Small epsilon for clean CSG -eps = 0.05; +// Small geometry tolerance +eps = 0.01; // ------------------------------------------------------------ -// 2D annular wedge sector -// Angle starts at 0 and runs to ang degrees +// Helper functions // ------------------------------------------------------------ -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)] ] +function deg(a) = a; +function lerp(a,b,t) = a + (b-a)*t; + +// u is normalized from 0 at left cut face to 1 at right cut face +// This defines the outside-elevation style profile: +// +// low edge -> bevel up -> flat table -> bevel down -> low edge +// +function crown_profile(u) = + let( + t0 = shoulder_frac, + t1 = 0.5 - table_frac/2, + t2 = 0.5 + table_frac/2, + t3 = 1.0 - shoulder_frac + ) + (u <= t0) ? lerp(0.00, 0.70, u / t0) : + (u <= t1) ? lerp(0.70, 1.00, (u - t0) / max(eps, t1 - t0)) : + (u <= t2) ? 1.00 : + (u <= t3) ? lerp(1.00, 0.70, (u - t2) / max(eps, t3 - t2)) : + lerp(0.70, 0.00, (u - t3) / max(eps, 1.0 - t3)); + +// Z value of top surface at station u +function top_z(u) = thickness + crown_height * crown_profile(u); + +// Angle at station i +function station_angle(i) = slice_angle * i / (stations - 1); + +// Polar point helpers +function p_inner(a,z) = [ inner_r * cos(a), inner_r * sin(a), z ]; +function p_outer(a,z) = [ outer_r * cos(a), outer_r * sin(a), z ]; + +// Indices for point grid +// per station: +// 0 = bottom inner +// 1 = bottom outer +// 2 = top inner +// 3 = top outer +function idx_bi(i) = 4*i + 0; +function idx_bo(i) = 4*i + 1; +function idx_ti(i) = 4*i + 2; +function idx_to(i) = 4*i + 3; + + +// ------------------------------------------------------------ +// Master wedge as a polyhedron +// Top shape traverses the wedge width +// ------------------------------------------------------------ + +module wedge_body() { + + pts = [ + for (i = [0:stations-1]) + let( + a = station_angle(i), + u = i / (stations - 1), + zt = top_z(u) + ) + each [ + p_inner(a, 0), // bottom inner + p_outer(a, 0), // bottom outer + p_inner(a, zt), // top inner + p_outer(a, zt) // top outer + ] + ]; + + faces = concat( + + // bottom, triangulated + [ + for (i = [0:stations-2]) each [ + [ idx_bi(i), idx_bi(i+1), idx_bo(i+1) ], + [ idx_bi(i), idx_bo(i+1), idx_bo(i) ] + ] + ], + + // top, triangulated + [ + for (i = [0:stations-2]) each [ + [ idx_ti(i), idx_to(i), idx_to(i+1) ], + [ idx_ti(i), idx_to(i+1), idx_ti(i+1) ] + ] + ], + + // inner radius face, triangulated + [ + for (i = [0:stations-2]) each [ + [ idx_bi(i), idx_ti(i), idx_ti(i+1) ], + [ idx_bi(i), idx_ti(i+1), idx_bi(i+1) ] + ] + ], + + // outer radius face, triangulated + [ + for (i = [0:stations-2]) each [ + [ idx_bo(i), idx_bo(i+1), idx_to(i+1) ], + [ idx_bo(i), idx_to(i+1), idx_to(i) ] + ] + ], + + // left cut face, triangulated + [ + [ idx_bi(0), idx_bo(0), idx_to(0) ], + [ idx_bi(0), idx_to(0), idx_ti(0) ] + ], + + // right cut face, triangulated + [ + [ idx_bi(stations-1), idx_ti(stations-1), idx_to(stations-1) ], + [ idx_bi(stations-1), idx_to(stations-1), idx_bo(stations-1) ] + ] ); - polygon(points = pts); + + polyhedron(points = pts, faces = faces, convexity = 12); } // ------------------------------------------------------------ -// Thin radial band of the wedge -// Used for hull() operations to create faceted crown surfaces +// Recessed bottom label so the base stays flat // ------------------------------------------------------------ -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) { +module wedge_label_cut(idx=0) { 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); + translate([x, y, label_depth + 0.2]) + mirror([0,0,1]) + rotate([180,0,mid_a - 90]) + linear_extrude(height = label_depth + 0.2) + text(str(idx), + size = label_size, + font = label_font, + halign = "center", + valign = "center"); } // ------------------------------------------------------------ -// Single wedge object +// One numbered wedge // ------------------------------------------------------------ module wedge_unit(idx=0) { - union() { - wedge_base(); - wedge_cap_simple(); - wedge_label(idx); + difference() { + wedge_body(); + wedge_label_cut(idx); } } // ------------------------------------------------------------ -// Full 10-part exploded wheel -// Each wedge is translated outward along its own centerline. +// Assemble 10 wedges around the center +// Each wedge is exploded outward along its centerline // ------------------------------------------------------------ module wheel_10() { @@ -163,7 +217,7 @@ module wheel_10() { // ------------------------------------------------------------ -// Top-level render +// Top level // ------------------------------------------------------------ -wheel_10(); +wheel_10(); \ No newline at end of file