$fn=64; // --- Parameters --- bowl_diameter = 180; // Diameter of the central cutout for the bowl stand_height = 120; // Total height of the stand top_thickness = 15; // Thickness of the top platform lip_width = 30; // Width of the top platform around the bowl leg_top_dia = 25; // Diameter of the legs at the top leg_bot_dia = 18; // Diameter of the legs at the bottom splay = 30; // Outward angle/distance of the legs for stability crossbar_height = 40; // Height of the support ring from the floor crossbar_thickness = 12; // Thickness of the support ring // --- Calculated Variables --- outer_size = bowl_diameter + (lip_width * 2); corner_offset = (outer_size / 2) - (leg_top_dia / 2) - 5; // Function to calculate leg center position at a given Z height function leg_pos(z) = corner_offset + splay * (1 - (z / (stand_height - top_thickness))); // --- Model --- difference() { union() { // Top Platform (Rounded Square) translate([0, 0, stand_height - top_thickness]) hull() { for (x = [-1, 1], y = [-1, 1]) { translate([x * corner_offset, y * corner_offset, 0]) cylinder(h=top_thickness, d=leg_top_dia + 10); } } // Splayed Legs for (x = [-1, 1], y = [-1, 1]) { hull() { // Top of the leg translate([x * corner_offset, y * corner_offset, stand_height - top_thickness]) cylinder(h=top_thickness, d=leg_top_dia); // Bottom of the leg translate([x * leg_pos(0), y * leg_pos(0), 0]) cylinder(h=1, d=leg_bot_dia); } } // Crossbar Support Ring for (i = [-1, 1]) { // X-axis crossbars hull() { translate([i * leg_pos(crossbar_height), -leg_pos(crossbar_height), crossbar_height]) sphere(d=crossbar_thickness); translate([i * leg_pos(crossbar_height), leg_pos(crossbar_height), crossbar_height]) sphere(d=crossbar_thickness); } // Y-axis crossbars hull() { translate([-leg_pos(crossbar_height), i * leg_pos(crossbar_height), crossbar_height]) sphere(d=crossbar_thickness); translate([ leg_pos(crossbar_height), i * leg_pos(crossbar_height), crossbar_height]) sphere(d=crossbar_thickness); } } } // Center cutout for the water bowl translate([0, 0, -1]) cylinder(h=stand_height + 2, d=bowl_diameter); // Flatten the bottom (removes any artifacts below floor level) translate([0, 0, -50]) cube([outer_size * 3, outer_size * 3, 100], center=true); }