with(plots);
with(plottools);
R_head := 1.3;
H_head := 0.75;
R_shaft := 0.45;
R_thread := 0.62;
pitch := 0.22;
n_turns := 16;
L_shank_smooth := 0.4;
L_thread := pitch*n_turns;
L_total := L_shank_smooth + L_thread;
hex_pts := [seq([R_head*cos(Pi*i/3), R_head*sin(Pi*i/3), 0], i = 0 .. 5)];
hex_top := [seq([R_head*cos(Pi*i/3), R_head*sin(Pi*i/3), H_head], i = 0 .. 5)];
sides := [seq([hex_pts[i], hex_pts[i + 1], hex_top[i + 1], hex_top[i]], i = 1 .. 5), [hex_pts[6], hex_pts[1], hex_top[1], hex_top[6]]];
head := polygonplot3d([hex_pts, hex_top, sides[]], style = surface, color = "DimGrey", lightmodel = light3);
shaft_smooth := display(plot3d([R_thread*cos(t), R_thread*sin(t), z], t = 0 .. 2*Pi, z = -L_shank_smooth .. 0, grid = [150, 5], style = surface, color = "Silver", lightmodel = light3), plot3d([r*cos(t), r*sin(t), 0], t = 0 .. 2*Pi, r = 0 .. R_thread, grid = [60, 15], style = surface, color = "Silver", lightmodel = light3), plot3d([r*cos(t), r*sin(t), -L_shank_smooth], t = 0 .. 2*Pi, r = 0 .. R_thread, grid = [60, 15], style = surface, color = "Silver", lightmodel = light3));
shaft_core := display(plot3d([R_shaft*cos(t), R_shaft*sin(t), z], t = 0 .. 2*Pi, z = -L_total .. -L_shank_smooth, grid = [150, 5], style = surface, color = "Silver", lightmodel = light3), plot3d([r*cos(t), r*sin(t), -L_shank_smooth], t = 0 .. 2*Pi, r = 0 .. R_shaft, grid = [60, 15], style = surface, color = "Silver", lightmodel = light3), plot3d([r*cos(t), r*sin(t), -L_total], t = 0 .. 2*Pi, r = 0 .. R_shaft, grid = [60, 15], style = surface, color = "Silver", lightmodel = light3));
R_prof := u -> R_shaft + (R_thread - R_shaft)*piecewise(u <= 0.5, 2*u, 2 - 2*u);
thread := plot3d([R_prof(u)*cos(t), R_prof(u)*sin(t), -L_shank_smooth - pitch*t/(2*Pi) + pitch*u], t = 0 .. 2*Pi*n_turns, u = 0 .. 1, grid = [320, 14], style = surface, color = "DimGray", lightmodel = light3);
frame := alpha -> display(rotate(head, alpha, [[0, 0, 0], [0, 0, 1]]), rotate(shaft_smooth, alpha, [[0, 0, 0], [0, 0, 1]]), rotate(shaft_core, alpha, [[0, 0, 0], [0, 0, 1]]), rotate(thread, alpha, [[0, 0, 0], [0, 0, 1]]), scaling = constrained, axes = normal, orientation = [0, 45]);
animate(frame, [alpha], alpha = 0 .. 2*Pi, frames = 60);