169 lines
4.4 KiB
OpenSCAD
169 lines
4.4 KiB
OpenSCAD
//
|
|
// color_wedge_chart.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();
|