$fn=500; // * b l only = "b"; // Global parameters passed cleanly into the modules radius = 19; cut_radius = 16.5; cut_squash = 0.85; height = 30; twist = 90; label1 = "40200"; label1_size = 3.8; label2 = ".2"; label2_size = 2.7; label3 = ".12"; label3_size = 2.7; if (only == "*" || only == "b") { color("blue") ball(radius=radius, cut_radius=cut_radius, height=height, twist=twist, label1=label1, label1_size=label1_size, label2=label2, label2_size=label2_size, label3=label3, label3_size=label3_size,render_text=false); } if (only == "*" || only == "l") { color("magenta") _ball_text(radius=radius, height=height, twist=twist, label1=label1, label1_size=label1_size, label2=label2, label2_size=label2_size, label3=label3, label3_size=label3_size); } module ball(radius, cut_radius, height, twist=90, slices=200, scale_base=0.5, label1, label1_size, label2, label2_size, label3, label3_size, render_text=true) { p_step = 2/slices; h_step = height/slices; t_step = twist/slices; sf_range = 1-scale_base; difference() { translate([0, 0, height/2]) union() { for (p=[-1 : p_step : 1-p_step]) { p2 = p+p_step; sf1 = scale_base + sf_range*cos(p*90); sf2 = scale_base + sf_range*cos(p2*90); translate([0, 0, p*(height/2)]) rotate([0, 0, p*(twist/2)]) scale([sf1, sf1, 1]) linear_extrude(height=h_step, twist=-t_step, scale=sf2/sf1) _ball_flat(radius=radius, cut_radius=cut_radius); } } _ball_text(radius=radius, height=height, twist=twist, label1=label1, label1_size=label1_size, label2=label2, label2_size=label2_size, label3=label3, label3_size=label3_size); } } module _ball_text(radius, height, twist, label1, label1_size, label2, label2_size, label3, label3_size) { // Counter the initial slice rotation rotate([0, 0, -1*(twist/2)]) linear_extrude(height=1.01, center=false) mirror([1, 0]) { if (label1 != "") { text(text=label1, font="JetBrains Mono", halign="center", valign="center", size=label1_size); } if (label2 != "") { translate([0, label1_size * 1.2, 0]) text(text=label2, font="JetBrains Mono", halign="center", valign="center", size=label2_size); } if (label3 != "") { translate([0, label1_size * -1.2, 0]) text(text=label3, font="JetBrains Mono", halign="center", valign="center", size=label3_size); } } } module _ball_flat(radius, cut_radius) { difference() { circle(r=radius); for (x=[-1, 1], y=[-1, 1]) { translate([x*radius, y*radius]) rotate([0, 0, 45 * x * y]) scale([cut_squash, 1, 1]) circle(r=cut_radius); } } }