works, but text is "cut" and hidden, committing now before removing "cut" and replacing with "raised"
This commit is contained in:
parent
b92f937e42
commit
c5dc13508a
1 changed files with 153 additions and 99 deletions
252
scad/wedge.scad
252
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();
|
||||
Loading…
Add table
Add a link
Reference in a new issue