$fn = 64; // --- PARAMETERS --- stand_width = 60; // Width of the stand base_length = 85; // Total depth of the base backrest_length = 75; // Length of the backrest backrest_angle = 65; // Angle of the backrest (degrees) phone_gap = 14; // Gap for the phone (fits most phones with cases) lip_height = 15; // Height of the front holding lip thickness = 6; // Thickness of the structural arms // --- CALCULATED POINTS --- // Offset by thickness/2 to keep all geometry positive and perfectly aligned pt_front_top = [thickness/2, thickness/2 + lip_height]; pt_front_bot = [thickness/2, thickness/2]; pt_base_back = [thickness/2 + base_length, thickness/2]; pt_backrest_bot = [thickness/2 + phone_gap + thickness, thickness/2]; pt_backrest_top = [ pt_backrest_bot[0] + backrest_length * cos(backrest_angle), pt_backrest_bot[1] + backrest_length * sin(backrest_angle) ]; // --- MODULES --- // Creates a thick line between two points with rounded ends module skeleton_line(p1, p2, t) { hull() { translate(p1) circle(d=t); translate(p2) circle(d=t); } } // --- MAIN GEOMETRY --- // Extruded and laid flat on its side for optimal 3D printing without supports linear_extrude(height = stand_width) { union() { // Front holding lip skeleton_line(pt_front_bot, pt_front_top, thickness); // Bottom base skeleton_line(pt_front_bot, pt_base_back, thickness); // Angled backrest skeleton_line(pt_backrest_bot, pt_backrest_top, thickness); // Rear support leg (forms a stable A-frame) skeleton_line(pt_backrest_top, pt_base_back, thickness); } }